从我的角度看,在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()实现背后的程序问题。
你觉得怎么样,为什么这样做呢?我不能第一个有这个问题,但是我找不到相关的话题?
在我谦虚的意见中,他们应该永远不会在JSF 1.2年龄期间将prependId属性添加到UIForm。只是为了保持j_security_check用户感到高兴,谁希望使用JSF表单与JSF输入组件(j_security_check需要精确的输入字段名称j_username和j_password,无法通过配置修改)。但是他们并没有明确指出,在JSF 1.2中,引入了另一项改进措施,使您能够继续使用< form>而不是坚持
只要不要使用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>。
也可以看看:
> How to select JSF components using jQuery?
> How to use JSF generated HTML element ID with colon “:” in CSS selectors?
> By default,JSF generates unusable ids,which are incompatible with css part of web standards