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

时间:2012-09-18 09:21:03

标签: jsf

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

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

据我所知,两种方式都有缺点: 组件绑定使用变量和getter / setter来破坏支持bean,一些站点强烈反对使用组件绑定。无论如何,建议使用请求范围。另一方面,findComponent()总是遍历树,这可能成本也可能不高,对吧? (另外,目前我根本找不到我的组件,但这是另一个问题)

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

1 个答案:

答案 0 :(得分:9)

首先,无论选择何种,两者都是不好的做法。另请参阅How does the 'binding' attribute work in JSF? When and how should it be used?

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

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

更简洁的方法是使用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>

这可以用作

<h:inputSome binding="#{components.input1}" />
<h:inputSome binding="#{components.input2}" />
<h:inputSome binding="#{components.input3}" />

这可以在其他bean中获得

Map<String, UIComponent> components = (Map<String, UIComponent>) externalContext.getRequestMap().get("components");

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


无关具体问题,正如您在其他问题中描述的那样,对于具体问题可能有一个更简单的解决方案,而不是在动作方法中执行验证(实际上是错误的设计)。我在那里发了一个答案。