带有prependId =“false”的UIForm中断<f:ajax render>
我对这个事实背后的想法有个疑问,那就是只有UIForm
得到了prependId
属性。 为什么在NamingContainer
接口中没有指定属性? 您现在可能会说这是因为向后兼容性,但我宁愿打破compability,让实现该接口的用户也实现prependId事物的方法。
从我的观点来看,关于UIForm
组件中的UIForm
的主要问题是,它会打破findComponent()
我期望,如果我使用prependId
,那么NamingContainer
行为将改变,不仅涉及到渲染,而且还希望搜索组件树中的组件。
这里有个简单的例子:
<h:form id="test" prependId="false"> <h:panelGroup id="group"/> </h:form>
现在,当我想要得到panelGroup组件,我希望传递字符串"group"
到方法findComponent()
,但它不会找到任何东西,我不得不使用"test:group"
。
具体的问题是,使用prependId="false"
时使用ajax。 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
将仅包含作为renderIds元素的id "group"
。 我不知道这是否预期,可能是但我不知道的代码。 现在我们来到findComponent()
方法找不到组件的地方,因为作为参数传递的表达式是方法期望"test:group"
查找组件的"test:group"
。
一种解决方法是编写你自己的findComponent()
,这是我选择处理这个问题的方式。 在这个方法中,我处理一个NamingContainer
组件,并且像普通的UIComponent
一样将属性prependId设置为false。 我将不得不为每个提供prependId属性的UIComponent
都这样做,这是不好的。 反射将有助于解决类型的静态定义,但它仍然不是一个真正干净的解决方案。
另一种方法是在NamingContainer
接口中引入prependId属性,并改变findComponent()
的行为以像上面描述的那样工作。
最后提出的解决方案是改变ajax标签的行为来传递整个id,但这只会解决ajax问题,而不是findComponent()
实现背后的程序性问题。
你怎么看待这个问题?为什么这个问题会被实现? 我不能成为第一个有这个问题,但我无法找到相关的主题?!
事实上,当使用<h:form prependId="false">
时,由<f:ajax render>
完成的UIComponent#findComponent()
失败。 这个问题是已知的,并且是“无法修复”: JSF规范问题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()
。 另请参见使用j_security_check在Java EE / JSF中执行用户认证 。
对于CSS选择器,如果您绝对需要一个ID选择器(因此不是一个更可重用的类选择器),只需将感兴趣的组件包装在纯HTML <div>
或<span>
。
也可以看看:
- 如何使用jQuery选择JSF组件?
- 如何在CSS选择器中使用带有冒号“:”的JSF生成的HTML元素ID?
- 默认情况下,JSF生成不可用的ID,这与Web标准的CSS部分不兼容