【问题标题】:how to update a wicket AjaxEditableMultiLineLabel model on an ajax call如何在 ajax 调用上更新检票口 AjaxEditableMultiLineLabel 模型
【发布时间】:2014-02-26 20:43:21
【问题描述】:

我尝试了多种方法,但均未成功。目前我的代码如下所示:

主页.html:

            <div wicket:id="text3" contenteditable="true">
            </div>

HomePage.java:

    public HomePage(final PageParameters parameters) {
//...

    AjaxEditableMultiLineLabel textArea = 
            new AjaxEditableMultiLineLabel ("text3", new PropertyModel (this, "text3") );


    textArea.add(new AjaxEventBehavior ("keyup") {

        @Override
        protected void onEvent(AjaxRequestTarget target) {
            System.out.println( "on event!" );
            System.out.println( getText3 () );
        }
    });
//...
}

/**
 * @return gets text3
 */
public String getText3() {
    return text3;
}

/**
 * @param text3
 *            the text3 to set
 */
public void setText3(String text3) {
    this.text3 = text3;
}

我想获取“div”中的内容,但它没有在 ajax 调用中更新。我可以强制它以某种方式发送吗?

顺便说一句,我想要实现的是每次更新时获取富文本区域的纯文本内容,以防在检票口中有更简单的方法。

【问题讨论】:

    标签: java ajax textarea wicket wicket-6


    【解决方案1】:

    您向不正确的 AjaxEditableMultiLineLabel 添加了 AjaxEventBehavior。 AjaxEditableMultiLineLabel 是一个包含两个组件的面板:

    • 标签
    • 编辑器(文本区域)

    任何 Ajax 行为都必须添加到任何这些组件中。在您的情况下,您必须向编辑器添加行为。

    (以下完整的工作示例在 https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-6.x/browse 上)

    标记

        <h2>Form</h2>
        <form wicket:id="form">
            <div wicket:id="text"></div>
            <input wicket:id="submit" type="submit" value="Send" />
        </form>
    
        <hr/>
    
        <h2>Result</h2>
        <div wicket:id="result">[result placeholder]</div>
    

    代码 sn-p

        final IModel<String> textModel = Model.of("initial text");
    
        Form<String> form = new Form<>("form", textModel);
        add(form);
    
        AjaxEditableMultiLineLabel<String> textArea = new AjaxEditableMultiLineLabel<String>(
                "text", textModel) {
    
            private static final long serialVersionUID = 1L;
    
            @Override
            protected FormComponent<String> newEditor(MarkupContainer parent,
                    String componentId, IModel<String> model) {
                final FormComponent<String> editor = super.newEditor(parent,
                        componentId, model);
    
                editor.add(new AjaxFormComponentUpdatingBehavior("keyup") {
    
                    private static final long serialVersionUID = 1L;
    
                    @Override
                    protected void onUpdate(AjaxRequestTarget target) {
                        System.out.println("Ajax update for textArea " + editor.getDefaultModelObjectAsString());
    
                    }
                });
    
                return editor;
            }
    
        };
    
        textArea.setCols(50);
        textArea.setRows(20);
    
        form.add(textArea);
        form.add(new SubmitLink("submit"));
    
        add(new Label("result", textModel));
    

    警告:之前的代码真的很慢

    代码很慢,因为每次按键/释放都会产生以下影响:

    1. 使用 textarea 的内容调用服务器
    2. 在服务器端调用代码(更新、渲染等)
    3. 在 XML 响应 (AJAX) 中将整个结果标记作为 html 发回
    4. 替换整个结果标签

    在本地主机上很慢,在真正的互联网上肯定不可用。

    解决方案

    使用简单的 jQuery 更新(JavaScript,jQuery 内置在 Wicket 6 中)

    带有 jQ​​uery 更新的代码 sn-p

        final IModel<String> textModel = Model.of("initial text");
        final Label result = new Label("result", textModel);
        result.setOutputMarkupId(true);
        add(result);
    
        Form<String> form = new Form<>("form", textModel);
        add(form);
    
        AjaxEditableMultiLineLabel<String> textArea = new AjaxEditableMultiLineLabel<String>(
                "text", textModel) {
    
            private static final long serialVersionUID = 1L;
    
            private boolean initialized = false;
    
            private FormComponent<String> editor;
    
            @Override
            public void onEdit(AjaxRequestTarget target) {
                super.onEdit(target);
                if(!initialized) {
                    String editorId = editor.getMarkupId();
                    String resultId = result.getMarkupId();
                    StringWriter sw = new StringWriter();
                    sw.write("$('#");
                    sw.write(editorId);
                    sw.write("').keyup(function() { var str = $('#");
                    sw.write(editorId);
                    sw.write("').val(); ");
                    sw.write("$('#");
                    sw.write(resultId);
                    sw.write("').html(str); });");
                    String js = sw.toString();
                    System.out.println("Appending editor JS " + js);
                    target.appendJavaScript(js);
                    initialized = true;
                }
            }
    
            @Override
            protected FormComponent<String> newEditor(MarkupContainer parent,
                    String componentId, IModel<String> model) {
                editor = super.newEditor(parent, componentId, model);
                return editor;
            }
    
        };
    
        textArea.setCols(50);
        textArea.setRows(20);
    
        form.add(textArea);
        form.add(new SubmitLink("submit"));
    

    【讨论】:

    • 谢谢,这让我走上了正轨。不幸的是,我不能使用那个确切的解决方案,因为 wicket 创建了一个不是“contenteditable”的内部 div 并且它显示纯文本,所以我需要做一些丑陋的 hack 来代替......
    • 那么,你的目标是什么?内容 div 真的有限制吗?如果你想在提交表单时更新你的模型,那么 AJAX 可以自己更新它并保持你的数据一致,以及你在表单中放置一个 textarea 标签。如果您对解决方案有更多了解,请发表评论。
    • 问题是 AjaxEditableMultiLineLabel 是用一个不是“contenteditable”的 div 块创建的,当您粘贴文本时,它会显示纯文本,剥离格式。这对我的应用程序至关重要。我想我应该将文本复制到一个隐藏的 div 并将其用于 ajax 调用,但我还没有一个可行的解决方案。
    • 所以你想显示 html 标签而不是替换它们的 html 实体?您可以设置使用 setEscapeModelStrings(false),记住,在标签上设置它(在我的示例中覆盖工厂方法 newLabel() 以及 newEditor());见stackoverflow.com/questions/1804220/…
    【解决方案2】:

    您应该将要更新的组件添加到 AjaxRequestTarget,如下所示:

    target.add(myComponent);
    

    您可以在 onEvent 方法中执行此操作,例如:

        @Override
        protected void onEvent(AjaxRequestTarget target) {
            System.out.println("on event!");
            System.out.println(getText3());
            target.add(textArea);
        }
    

    关于富文本区域模型的问题,您可以使用普通模型,您的代码如下所示:

     public HomePage(final PageParameters parameters) {
        private Model<String> textModel;
    
        Model<String> textModel = Model.of("");
        AjaxEditableMultiLineLabel textArea = new AjaxEditableMultiLineLabel ("text3", textModel);
    
    
        textArea.add(new AjaxEventBehavior ("keyup") {
    
            @Override
            protected void onEvent(AjaxRequestTarget target) {
                System.out.println(textModel.getObject());
            }
        });
    //...
    }
    

    我猜差别不大,但您只使用一个模型,而不是字符串属性和模型。

    【讨论】:

    • 我试过了 (target.add(myComponent); ) 但还是不行。还是谢谢你的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-16
    • 1970-01-01
    相关资源
    最近更新 更多