检票口 AJAX +组件标签上

发布于 2024-09-11 13:44:49 字数 805 浏览 4 评论 0原文

嗨,大家好, 我想将 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);
    }

   });

非常感谢您的帮助! CU

HI guys,
I wanted to add an AJAX Event to my Homepage, but it doesn't work! I figured out, that if I delete the onComponentTag function it works well. I have no clue why this happend, maybe you can help me!
Thats my Code:

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

   });

Thx a lot for helping me!
CU

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

苍暮颜 2024-09-18 13:44:49

首先,您根本不需要重写 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 更合适吗?

Firstly, you don't need to be overriding onComponentTag() at all. As seanizer states, if your really need to specify a markup ID yourself, use setMarkupId(id). You should understand why it is recommended that Wicket manages component IDs.

Secondly, the value attribute that you are adding is unnecessary - Wicket adds this automatically for this component. The value assigned is the value of the component's model object. See the source for TextField.onComponentTag().

Thirdly, again as seanizer states, components that are to be updated by ajax need to output their markup IDs - Wicket's ajax implementation uses the ID as the selector for the element. Additionally, all Wicket ajax behaviours that extend AbstractDefaultAjaxBehavior automatically set outputMarkupId(true) on the component they are bound to (see the source for AbstractDefaultAjaxBehavior.onBind()). This includes AjaxFormComponentUpdatingBehavior.

So:

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

Finally, I'd question what you're actually trying to achieve with this behaviour. I don't see any reason to round-trip this event to the server. Surely some client-side JS is more appropriate?

安稳善良 2024-09-18 13:44:49
tag.put("id", this.getId());

不是在检票口这样做的方法。

相反,使用

component.setOutputMarkupId(true)

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

component.setMarkupId("myId")

也可以这样做,你可能不应该自己分配标签值,使用模型(模型处理在 wicket 中非常智能,请阅读 有关模型的更多信息)。 onComponentTag 有有效的用途,但它们远远超出了您正在做的事情。让 wicket 做他最擅长的事情,一切都会好起来的。


编辑:
好的,更多说明

请参见 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 检票口写入的内容是 id 检票口知道的。如果这不会呈现 id,您可能会通过覆盖 onComponentTag 来破坏某些默认行为。

看看 组件的源代码,特别是在 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());
    }
}

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

现在,如果像你的情况一样,你想手动设置组件id,你必须 可以使用

component.setMarkupId("myId")

当然

setOutputMarkupId(true)

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

tag.put("id", this.getId());

is not the way to do it in wicket.

instead, use

component.setOutputMarkupId(true)

(either in your component constructor or in your behavior's bind() method) to make wicket write the id, and if you absolutely need to control what the id is (which is almost never the case) you can do

component.setMarkupId("myId")

also, you probably shouldn't assign the tag value yourself, use a model (model handling is extremely smart in wicket, read more about models). There are valid uses for onComponentTag, but they are way beyond what you are doing. Let wicket do what wicket does best and everything will be fine.


EDIT:
OK, some more clarification

have a look at the source code of AjaxFormComponentUpdatingBehavior, especially the part where the javascript event handler is generated.

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

as you can see, wicket uses getMarkupId() to determine the actual id. The id you set using tag.put(id) is totally unknown to wicket and hence the behavior cannot work.

The standard thing to do is setOutputMarkupId(true). This is the only proper way to tell wicket to render the id (other than setOutputMarkupPlaceholder(true), which internally calls the former method). That way you make sure that the id wicket writes is the id wicket knows about. If this doesn't render the id, you are probably breaking some default behavior by overwriting onComponentTag.

Have a look at the source code of Component, especially at onComponentTag(), the method you are overriding:

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());
    }
}

[The comments are mine. BTW, this is the source of an ancient version, but I didn't find any current source online, and the functionality hasn't changed.]

Now if, as in your case, you want to set the component id manually, you must use

component.setMarkupId("myId")

and of course

setOutputMarkupId(true)

as well. If that doesn't work, go to the wicket JIRA site and file a bug. But I doubt it, this is standard functionality that works for thousands of users.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文