Wicket AJAX + OnComponentTag

Syl*_*vus 2 java ajax wicket

嗨伙计们,我想在我的主页上添加一个AJAX活动,但它不起作用!我想,如果我删除onComponentTag函数,它运行良好.我不知道为什么会发生这种情况,也许你可以帮助我!那是我的代码:

  final TextField<String> searchInput = new TextField<String>("searchInput", model) {

    @Override
    protected void onComponentTag(final ComponentTag tag) {
     super.onComponentTag(tag);
     tag.put("id", this.getId());
     if (params.getString("search") != null) {
      tag.put("value", params.getString("search"));
     }
    }
   };

   searchInput.add(new AjaxFormComponentUpdatingBehavior("onfocus") {
    @Override
    protected void onUpdate(final AjaxRequestTarget target) {
     System.out.print("never saw that message :(");
     searchInput.setDefaultModelObject("");
     target.addComponent(searchInput);
    }

   });
Run Code Online (Sandbox Code Playgroud)

对我有很大的帮助!CU

Sea*_*oyd 5

tag.put("id", this.getId());
Run Code Online (Sandbox Code Playgroud)

不是在检票口做的方法.

相反,使用

component.setOutputMarkupId(true)
Run Code Online (Sandbox Code Playgroud)

(在你的组件构造函数或你的行为的bind()方法中)使wicket写入id,如果你绝对需要控制id是什么(几乎不是这种情况)你可以做

component.setMarkupId("myId")
Run Code Online (Sandbox Code Playgroud)

另外,你可能不应该自己分配标签值,使用模型(模型处理在wicket中非常聪明,阅读更多关于模型的信息).onComponentTag有一些有效的用途,但它们远远超出了你的工作范围.让检票口做最好的检票口,一切都会好的.


编辑:好的,更多的澄清

看看AjaxFormComponentUpdatingBehavior的源代码,特别是生成javascript事件处理程序的部分.

protected final CharSequence getEventHandler()
{
    return generateCallbackScript(
                    new AppendingStringBuffer("wicketAjaxPost('")
                    .append(getCallbackUrl(false)).append(
        "', wicketSerialize(Wicket.$('" 
                         + getComponent().getMarkupId() + "'))"));
}
Run Code Online (Sandbox Code Playgroud)

如你所见,wicket使用getMarkupId()来确定实际的id.你使用tag.put(id)设置的id对于wicket是完全不为人知的,因此行为不起作用.

标准的事情是setOutputMarkupId(true).这是告诉wicket呈现id的唯一正确方法(除了setOutputMarkupPlaceholder(true),内部调用前一个方法).这样你就可以确保id wicket写的是wicket知道的id.如果这不呈现id,则可能通过覆盖onComponentTag来破坏某些默认行为.

看一下Component的源代码,特别是在onComponentTag()中,你要覆盖的方法:

protected void onComponentTag(final ComponentTag tag) {
    // if(setOutputMarkupId(true) was set)
    if (getFlag(FLAG_OUTPUT_MARKUP_ID)) {

        // set id attribute
        tag.put(MARKUP_ID_ATTR_NAME, getMarkupId());
    }
}
Run Code Online (Sandbox Code Playgroud)

[评论是我的.顺便说一句,这是一个古老版本的来源,但我没有在网上找到任何当前的来源,并且功能没有改变.]

现在,如果您要手动设置组件ID,则必须使用

component.setMarkupId("myId")
Run Code Online (Sandbox Code Playgroud)

当然的

setOutputMarkupId(true)
Run Code Online (Sandbox Code Playgroud)

同样.如果这不起作用,请转到检票口JIRA网站并提交错误.但我对此表示怀疑,这是适用于成千上万用户的标准功能.


ire*_*ick 5

首先,您根本不需要重写onComponentTag().正如seanizer所述,如果您确实需要自己指定标记ID,请使用setMarkupId(id).您应该理解为什么建议Wicket管理组件ID.

其次,您添加的value属性是不必要的 - Wicket会自动为此组件添加此属性.分配的值是组件的模型对象的值.请参阅TextField.onComponentTag()的源代码.

第三,再次作为seanizer状态,由ajax更新的组件需要输出其标记ID - Wicket的ajax实现使用ID作为元素的选择器.此外,扩展AbstractDefaultAjaxBehavior的所有Wicket ajax行为都会自动在它们绑定的组件上设置outputMarkupId(true)(请参阅AbstractDefaultAjaxBehavior.onBind()的源代码).这包括AjaxFormComponentUpdatingBehavior.

所以:

String id = "searchInput";
final TextField<String> searchInput = new TextField<String>(id, model);
searchInput.setMarkupId(id);

searchInput.add(new AjaxFormComponentUpdatingBehavior("onfocus") {
  @Override
  protected void onUpdate(final AjaxRequestTarget target) {
    System.out.print("never saw that message :(");
    searchInput.setDefaultModelObject("");
    target.setOutputMarkupId(true);
    target.addComponent(searchInput);
  }
});
Run Code Online (Sandbox Code Playgroud)

最后,我会质疑你实际上试图通过这种行为实现的目标.我认为没有理由将此事件往返于服务器.当然有些客户端JS更合适吗?