我对事实背后的想法有一个疑问,即只有UIForm
才具有prependId
属性。为什么在NamingContainer
接口(interface)中未指定属性?您现在可能会说这是由于向后兼容性,但是我更希望破坏兼容性,让实现该接口(interface)的用户也为prependId事物实现方法。
从我的 Angular 来看,关于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
一样处理一个组件UIComponent
,并将属性prependId设置为false。对于每个提供prependId属性的UIComponent
,我都必须这样做,这很糟糕。反射将有助于绕过类型的静态定义,但它仍然不是一个真正干净的解决方案。另一种方法是在
NamingContainer
接口(interface)中引入prependId属性,并将findComponent()
的行为更改为如上所述工作。最后提出的解决方案是更改ajax标签的行为以传递整个id,但这只能解决ajax问题,而不能解决
findComponent()
实现背后的编程问题。您对此有何看法,为什么会这样实现呢?我不能成为第一个遇到此问题的人,但找不到相关主题?
最佳答案
实际上,当使用UIComponent#findComponent()
时,由<f:ajax render>
完成的<h:form prependId="false">
失败。这个问题是已知的,并且是“无法解决”的问题:JSF spec issue 573。
以我的拙见,在JSF 1.2时代,他们永远不应该在prependId
中添加UIForm
属性。这样做只是为了让j_security_check
用户满意,他们希望为此使用带有JSF输入组件的JSF表单(j_security_check
需要精确的输入字段名称j_username
和j_password
,无法通过配置进行修改)。但是他们并没有完全意识到,在JSF 1.2中引入了另一项改进,使您可以继续使用<form>
而不是坚持使用<h:form>
。然后CSS / jQuery纯粹主义者开始滥用prependId="false"
以避免在选择不佳的CSS选择器中转义分隔符:
。
只是永远不要使用prependId="false"
。
对于j_security_check
,只需使用<form>
或新的Servlet 3.0 HttpServletRequest#login()
即可。另请参见Performing user authentication in Java EE / JSF using j_security_check。
对于CSS选择器,万一您绝对需要一个ID选择器(因此不需要更可重用的类选择器),只需将所需的组件包装在纯HTML <div>
或<span>
中即可。
也可以看看: