UIForm与prependId =“false”中断
我有一个关于这个事实背后的想法的问题,只有UIForm获得了属性prependId。为什么在NamingContainer界面中未指定属性?你现在可能会说这是因为后向可执行性,但是我宁愿打破可比性,并让实现该接口的用户也实现了prependId的方法。
从我的角度看,在UIForm组件中的prependId的主要问题是它会中断findComponent() 这里有一个简单的例子: <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()实现背后的程序问题。 你觉得怎么样,为什么这样做呢?我不能第一个有这个问题,但是我找不到相关的话题?
实际上,由< f:ajax render>完成的UIComponent#findComponent()使用< 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>而不是坚持
只要不要使用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? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |