【问题标题】:Wicket AJAX + OnComponentTagWicket AJAX + OnComponentTag
【发布时间】:2010-07-26 11:16:27
【问题描述】:

大家好, 我想在我的主页中添加一个 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);
    }

   });

非常感谢您对我的帮助! 铜

【问题讨论】:

    标签: java ajax wicket


    【解决方案1】:

    首先,您根本不需要重写 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);
      }
    });
    

    最后,我想问一下您实际上想通过这种行为实现什么。我看不出有任何理由将此事件往返于服务器。确定一些客户端JS更合适?

    【讨论】:

    • 你忘记了 setOutputMarkupId(true) :-)
    • 查看 AbstractDefaultAjaxBehavior.onBind() 的源代码 - 行为为您设置了标志(抱歉,这不清楚 - 我已经编辑了答案以使其更清晰)。
    【解决方案2】:
    tag.put("id", this.getId());
    

    不是在检票口中做到这一点的方法。

    改为使用

    component.setOutputMarkupId(true)
    

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

    component.setMarkupId("myId")
    

    另外,您可能不应该自己分配标签值,而是使用模型(模型处理在检票口中非常聪明,阅读more about models)。 onComponentTag 有一些有效的用途,但它们远远超出了您正在做的事情。让 wicket 做 wicket 最擅长的事情,一切都会好起来的。


    编辑: 好的,再澄清一点

    看看the source code of AjaxFormComponentUpdatingBehavior,尤其是生成javascript事件处理程序的部分。

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

    如您所见,wicket 使用 getMarkupId() 来确定实际 id。您使用 tag.put(id) 设置的 id 对 wicket 是完全未知的,因此该行为无法正常工作。

    标准的做法是setOutputMarkupId(true)。这是告诉 wicket 呈现 id 的唯一正确方法(除了 setOutputMarkupPlaceholder(true),它在内部调用前一种方法)。这样,您可以确保 id wicket 写入的 id wicket 知道。如果这不呈现 id,您可能会通过覆盖 onComponentTag 来破坏某些默认行为。

    查看the source code of 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());
        }
    }
    

    [cmets 是我的。 BTW,这是一个古版本的来源,但是我在网上没有找到任何现在的来源,并且功能没有改变。]

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

    component.setMarkupId("myId")
    

    当然

    setOutputMarkupId(true)
    

    也是。如果这不起作用,请访问 wicket JIRA 站点并提交错误。但我对此表示怀疑,这是适用于成千上万用户的标准功能。

    【讨论】:

    • 抱歉,我无法关注你。 1)我尝试了 setOutputMarkupId(true) 但它没有打印出我的身份证!我的 CSS 需要一个 ID! 2)我从不想更改 ID,也永远不会:) 3)这并不能解决我的问题 :( 也许我不够聪明 :) 请帮忙!
    • 查看我的更新答案。你需要同时使用 setMarkupId(myId) 和 setOutputMarkupId(true)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-01
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多