组件绑定vs findComponent() - 何时使用哪个?

Lou*_*ise 6 jsf

正如在这个问题中所描述的,我尝试在辅助bean端的表单中执行一些字段验证.为此,我想访问违规字段来标记它们.通过搜索网络,似乎有两种方法可以做到这一点:

  • 将组件存储在backing bean中以供访问,并通过该binding属性在JSF页面中使用它们.
  • 在JSF页面中使用标准值绑定,当需要从bean访问组件时,请通过查找 UIViewRoot.findComponent(String id)

至于我可以看到这两种方法都有缺点:组件绑定炸毁支持bean与变量和getter/setter方法,一些网站极力劝阻结合在所有使用组件.无论如何,建议使用请求范围.另一方面,findComponent()总是遍历树,这可能成本也可能不高,对吧?(另外,目前我根本找不到我的组件,但这是另一个问题)

哪条路可走?这些是可互换的替代品,如果没有,根据您选择的标准?目前我只是没有足够的洞察力做出正确的决定......

Bal*_*usC 9

首先,无论选择何种,两者都是不好的做法.另请参见"绑定"属性如何在JSF中起作用?应该何时以及如何使用?

如果你必须做出选择,组件绑定肯定更快,更便宜.从逻辑上讲,完全意义上的树扫描UIComponent#findComponent()具有其性能影响.

实际上,持有组件绑定的辅助bean 必须是请求作用域,但您可以轻松地注入一个不同的作用域支持bean,其中包含业务逻辑@ManagedProperty.

更简洁的方法是使用Map所有组件绑定的持有者.您只需要将以下条目添加到faces-config.xml:

<managed-bean>
    <managed-bean-name>components</managed-bean-name>
    <managed-bean-class>java.util.HashMap</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
</managed-bean>
Run Code Online (Sandbox Code Playgroud)

这可以用作

<h:inputSome binding="#{components.input1}" />
<h:inputSome binding="#{components.input2}" />
<h:inputSome binding="#{components.input3}" />
Run Code Online (Sandbox Code Playgroud)

这可以在其他bean中获得

Map<String, UIComponent> components = (Map<String, UIComponent>) externalContext.getRequestMap().get("components");
Run Code Online (Sandbox Code Playgroud)

这样您就不必担心指定单个属性/ getter/setter.在上面的示例中,Map将包含带有键的三个条目input1,input2并且input3每个条目都具有相应的UIComponent实例作为值.


具体问题无关,对于具体问题的解决方案可能比在其他问题中描述的要简单得多,而不是在动作方法中执行验证(实际上是Bad Design).我在那里发布了答案.