6

本问题所述,我尝试在支持 bean 端的表单中执行一些字段验证。为此,我想访问违规字段以标记它们。从网上搜索似乎有两种方法可以做到这一点:

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

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

哪条路要走?这些是可互换的替代方案吗?如果不是,您选择的标准是什么?目前我只是没有足够的洞察力来做出一个体面的决定......

4

1 回答 1

9

首先,无论选择哪种方式,两者都是不好的做法。另请参阅JSF 中的“绑定”属性如何工作?何时以及如何使用它?

如果您必须做出选择,组件绑定肯定更快更便宜。从逻辑上完全理解,由 完成的树扫描UIComponent#findComponent()具有其性能影响。

实际上,包含组件绑定的支持 bean必须是请求范围的,但是您可以轻松地注入一个不同范围的支持 bean,通过@ManagedProperty.

一种更简洁的方法是使用 aMap作为所有组件绑定的持有者。您只需将以下条目添加到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将包含三个带有键和的条目input1,每个条目都有各自的实例作为值。input2input3UIComponent


与具体问题无关,对于您在另一个问题中描述的具体问题,可能有一个更简单的解决方案,而不是在操作方法中执行验证(这实际上是糟糕的设计)。我已经在那里发布了答案。

于 2012-09-18T12:51:20.517 回答