当前位置: 首页 > 面试题库 >

带有prependId =“ false”的UIForm中断

傅志诚
2023-03-14
问题内容

我对事实背后的想法有一个疑问,那就是只有UIForm这个属性prependId。为什么在NamingContainer接口中未指定属性?您现在可能会说这是由于向后兼容性,但是我更愿意破坏兼容性,让实现该接口的用户还为prependId事情实现方法。

UIForm组件中的prependId而言,我的主要问题是,它会中断,findComponent()
我希望如果我使用prependIdNamingContainer行为会发生变化,不仅与渲染有关,而且还与想要在组件树中搜索组件有关。

这里有个简单的例子:

<h:form id="test" prependId="false">
  <h:panelGroup id="group"/>
</h:form>

现在,当我想获取panelGroup组件时,我希望将字符串传递"group"给method
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()这是我选择解决此问题的方法。在这种方法中,我处理一个组件,该组件是a,NamingContainer并且像通常一样将prependId属性设置为false
UIComponent。对于每UIComponent一个提供prependId属性的属性,我都将不得不这样做。反射将有助于绕过类型的静态定义,但它仍然不是一个真正干净的解决方案。

另一种方法是在NamingContainer接口中引入prependId属性,并更改行为以findComponent()使其如上所述工作。

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

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


问题答案:

确实,使用时,UIComponent#findComponent()操作<f:ajax render>失败<h:form prependId="false">。这个问题是已知的,并且是“无法解决”的问题:JSF规范问题573。

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

只是prependId="false"永远不要使用。

对于j_security_check,只需使用<form>或新的Servlet 3.0
HttpServletRequest#login()

对于CSS选择器,万一您绝对需要一个ID选择器(因此不需要更可重用的类选择器),只需将所需的组件包装在纯HTML <div>或中即可<span>



 类似资料:
  • Mkdirs()函数在Android11上不起作用。在Android10及更低版本上,一切都运行良好。 代码: 以上代码在Android 10或更低版本的情况下返回true。但在Android11的情况下返回false。清单权限: 注意到要考虑相同的运行时权限(READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE)。 清单应用程序: 我能够在外部存储中写入的唯一

  • 为什么当使用括号时,这些语句会像预期的那样工作: 但是当没有括号时,它返回?

  • 问题内容: 和JPA持久性之间有什么区别? 问题答案: Gordon Yorke(EclipseLink体系结构委员会成员,TopLink核心技术负责人,JPA 2.0专家组成员)在此主题上写了一个很好的答案,因此,我不用表述他,而是引用他的答案: 和 之间的区别是评估它们的范围。’ ‘ 的定义讨论了属性和字段值,并建议应在运行时内评估此功能。“ ”仅指数据库列。 如果实现选择实现,则这些属性应由

  • 问题内容: 使用括号时,这些语句为什么能按预期工作: 但是 ,如果没有括号,它会返回吗? 问题答案: 基于有关操作符优先级的python 文档 : 请注意,比较,成员资格测试和身份测试均具有相同的优先级,并且具有“比较”部分中所述的从左到右的 链接 功能。 因此,实际上您有一个链接语句,如下所示: 您可以假定中心对象将在2个操作和其他对象之间共享(在这种情况下为False)。 并且请注意,对于所有

  • 问题内容: 我试过运行这段代码: 并输出 False 。我认为Python会将任何有价值的东西都视为 True 。为什么会这样呢? 问题答案: 从 6.11开始。 布尔运算: 在布尔运算的上下文中,以及当控制流语句使用表达式时,以下值将解释为false:False,None,所有类型的数字零以及空字符串和容器(包括字符串,元组,列表,字典) ,集合和Frozensets)。所有其他值均解释为tru

  • 问题内容: 如果我这样做: 那又回来了。仅仅是因为在列表中。 但是,如果我这样做: 那又回来了。而等于: 为什么? 问题答案: 运算符优先级 2.x,3.x。的优先级低于的优先级。因此,它等效于: 这就是你想要的: 正如@Ben指出的那样:建议从不写作,更喜欢。前者使它看起来像一个函数调用,而它却是一个运算符,而不是一个函数。