20

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

从我的角度来看,关于组件中 prependId 的主要问题UIForm是,它会破坏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()这是我选择处理此问题的方式。在这种方法中,我处理一个组件,它是 aNamingContainer并且其属性 prependId 设置为 false ,就像普通的一样UIComponentUIComponent对于每个提供 prependId 属性的东西,我都必须这样做,这很糟糕。反射将有助于绕过类型的静态定义,但它仍然不是一个真正干净的解决方案。

另一种方法是在界面中引入 prependId 属性NamingContainer并改变行为findComponent()以像上面描述的那样工作。

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

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

4

1 回答 1

19

事实上,UIComponent#findComponent()正如<f:ajax render>使用失败时所做的那样<h:form prependId="false">。这个问题是已知的并且是“无法修复”:JSF 规范问题 573

在我看来,他们不应该在 JSF 1.2 时代将prependId属性添加到。UIForm这样做只是为了让j_security_check希望使用带有 JSF 输入组件的 JSF 表单的用户满意(j_security_check需要准确的输入字段名称j_usernamej_password并且不能通过配置进行修改)。但他们并没有完全意识到在 JSF 1.2 期间引入了另一项改进,使您能够继续使用<form>而不是坚持使用<h:form>. 然后 CSS/jQuery 纯粹主义者开始滥用prependId="false",以避免:在他们选择不当的 CSS 选择器中转义分隔符。

永远不要使用prependId="false"

对于j_security_check,只需使用<form>或新的 Servlet 3.0 HttpServletRequest#login()。另请参阅使用 j_security_check 在 Java EE/JSF 中执行用户身份验证

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

也可以看看:

于 2011-09-14T13:04:29.727 回答