;" />

UIForm 与 prependId="false"中断 ;

发布于 2024-12-04 15:48:37 字数 1878 浏览 4 评论 0 原文

我对只有 UIForm 获得属性 prependId 背后的想法有疑问。为什么 NamingContainer 接口中未指定该属性?您现在可能会说这是因为向后兼容性,但我更愿意打破兼容性并让实现该接口的用户也实现 prependId 事物的方法。

从我的角度来看,UIForm 组件中 prependId 的主要问题是,它会破坏 findComponent() 我希望如果我使用 prependId,那么 NamingContainer 行为将会改变,不仅与渲染相关,而且在想要在组件树中搜索组件时也相关。

这是一个简单的例子:

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>

现在,当我想要获取 panelGroup 组件时,我希望将字符串 "group" 传递给方法 findComponent(),但它不会找到任何东西,我必须使用 "test:group" 代替。

具体问题是,当将 ajax 与 prependId="false" 一起使用时。 ajax 标签期望在属性更新和处理中,值关心命名容器。有点奇怪的是,当我使用 prependId="false" 时,我必须指定完整的 id 或路径,但是没关系。

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
  <h:commandButton value="go">
    <f:ajax render="test:group"/>
  </h:commandButton>
</h:form>

好吧,这段代码将毫无问题地呈现,但它不会更新 panelGroup,因为它找不到它。 PartialViewContext 将仅包含 id "group" 作为 renderIds 的元素。我不知道这是否是预期的,可能是,但我不知道代码。现在我们遇到了 findComponent() 方法无法找到组件的情况,因为作为参数传递的表达式是 "group" ,而该方法需要 " test:group" 来查找组件。

一种解决方案是编写您自己的 findComponent(),这是我选择处理此问题的方法。在此方法中,我处理一个 NamingContainer 组件,并且将属性 prependId 设置为 false,就像普通的 UIComponent 一样。我必须对每个提供 prependId 属性的 UIComponent 执行此操作,但这很糟糕。反射将有助于绕过类型的静态定义,但它仍然不是一个真正干净的解决方案。

另一种方法是在 NamingContainer 接口中引入 prependId 属性,并更改 findComponent() 的行为,使其按上述方式工作。

最后提出的解决方案是更改 ajax 标记的行为以传递整个 id,但这只能解决 ajax 问题,而不能解决 findComponent() 实现背后的编程问题。

您对此有何看法?为什么要这样实施?我不是第一个遇到这个问题的人,但我找不到相关主题?!

I have a question about the idea behind the fact, that only UIForm got the attribute prependId. Why is the attribute not specified in the NamingContainer interface? You will now probably say that's because of backward compability but I would preferre breaking the compability and let users which implement that interface, also implement methods for the prependId thing.

The main problem from my perspective about the prependId in the UIForm component is, that it will break findComponent()
I would expect that if I use prependId, then the NamingContainer behaviour would change, not only related to rendering but also when wanting to search for components in the component tree.

Here a simple example:

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>

Now when i want to get the panelGroup component I would expect to pass the string "group" to the method findComponent(), but it won't find anything, I have to use "test:group" instead.

The concrete problem with that is, when using ajax with prependId="false". The ajax tag expects in the attributes update and process, that the values care of naming containers. It's a bit strange that when I use prependId="false" that I have to specify the full id or path, but okay.

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>
<h:form id="test1" prependId="false">
  <h:commandButton value="go">
    <f:ajax render="test:group"/>
  </h:commandButton>
</h:form>

Well this code will render without problems but it won't update the panelGroup because it cannot find it. The PartialViewContext will contain only the id "group" as element of the renderIds. I don't know if this is expected, probably it is but I don't know the code. Now we come to the point where the method findComponent() can not find the component because the expression passed as parameter is "group" where the method would expect "test:group" to find the component.

One solution is to write your own findComponent() which is the way I chose to deal with this problem. In this method i handle a component which is a NamingContainer and has the property prependId set to false like a normal UIComponent. I will have to do that for every UIComponent which offers a prependId attribute and that is bad. Reflection will help to get around the static definition of types but it's still not a really clean solution.

The other way would be introducing the prependId attribute in the NamingContainer interface and change the behaviour of findComponent() to work like described above.

The last proposed solution would be changing the behaviour of the ajax tag to pass the whole id, but this would only solve the ajax issue and not the programmatic issues behind the findComponent() implementation.

What do you think about that and why the hell is it implemented like that? I can't be the first having this problem, but I wasn't able to find related topics?!

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

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

发布评论

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

评论(1

感悟人生的甜 2024-12-11 15:48:37

事实上,当使用 < 时,由 完成的 UIComponent#findComponent() 会失败/代码>。此问题是已知的并且“无法修复”: JSF 规范问题 573

以我的拙见,在 JSF 1.2 时代,他们不应该将 prependId 属性添加到 UIForm 中。这样做只是为了让想要使用带有 JSF 输入组件的 JSF 表单的 j_security_check 用户满意(j_security_check 需要精确的输入字段名称 j_username code> 和 j_password 无法通过配置修改)。但他们并没有完全意识到,在 JSF 1.2 期间引入了另一项改进,使您能够继续使用

而不是坚持使用 代码>.然后 CSS/jQuery 纯粹主义者开始滥用 prependId="false" 来避免在他们选择不当的 CSS 选择器中转义分隔符 :

只是永远不要使用 prependId="false"

对于 j_security_check,只需使用

或新的 Servlet 3.0 HttpServletRequest#login()。另请参阅执行用户身份验证Java EE / JSF 使用 j_security_check

对于 CSS 选择器,如果您绝对需要 ID 选择器(因此不是更可重用的类选择器),只需将感兴趣的组件包装在纯 HTML

<; 中即可。跨度>

另请参阅:

Indeed, UIComponent#findComponent() as done by <f:ajax render> fails when using <h:form prependId="false">. This problem is known and is a "Won't fix": JSF spec issue 573.

In my humble opinion, they should never have added the prependId attribute to the UIForm during the JSF 1.2 ages. It was merely done to keep j_security_check users happy who would like to use a JSF form with JSF input components for that (j_security_check requires exact input field names j_username and j_password which couldn't be modified by configuration). But they didn't exactly realize that during JSF 1.2 another improvement was introduced which enables you to just keep using <form> for that instead of sticking to <h:form>. And then CSS/jQuery purists start abusing prependId="false" to avoid escaping the separator character : in their poorly chosen CSS selectors.

Just don't use prependId="false", ever.

For j_security_check, just use <form> or the new Servlet 3.0 HttpServletRequest#login(). See also Performing user authentication in Java EE / JSF using j_security_check.

For CSS selectors, in case you absolutely need an ID selector (and thus not a more reusable class selector), simply wrap the component of interest in a plain HTML <div> or <span>.

See also:

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