如何在ajax调用上更新wicket AjaxEditableMultiLineLabel模型

时间:2014-02-03 11:23:44

标签: java ajax textarea wicket wicket-6

我尝试过多次没有成功的事情。目前我的代码看起来像这样:

HomePage.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;
}

我希望获得&#34; div&#34;但它没有在ajax调用上更新。我可以强迫它以某种方式发送它吗?

顺便说一句,我想要实现的是每次更新时都会获得富文本区域的纯文本内容,以防有更简单的方法在wicket中进行。

2 个答案:

答案 0 :(得分:2)

将AjaxEventBehavior添加到NOT CORRECT的AjaxEditableMultiLineLabel。 AjaxEditableMultiLineLabel是一个包含两个组件的Panel:

  • 标签
  • 编辑(textarea)

任何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>

代码段

    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. 在服务器端调用代码(更新,渲染等)
  4. 将整个结果标记作为html发送回XML响应(AJAX)
  5. 替换整个结果标记
  6. 在localhost上很慢,在真正的互联网上肯定是无法使用的。

    <强>解

    使用简单的jQuery更新(JavaScript,jQuery是在Wicket 6中构建的)

    jQuery更新的代码段

        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"));
    

答案 1 :(得分:1)

您应该将要更新的组件添加到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());
        }
    });
//...
}

我猜没有太大区别,但你只使用一个模型,而不是String属性和模型。