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

Posted

技术标签:

【中文标题】组件绑定与 findComponent() - 何时使用哪个?【英文标题】:component binding vs findComponent() - when to use which? 【发布时间】:2012-09-10 12:57:08 【问题描述】:

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

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

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

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

【问题讨论】:

this other forum 中的相同问题,但唉,没有答案 ;) 【参考方案1】:

首先,无论选择哪种方式,两者都是不好的做法。另见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 实例作为值。


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

【讨论】:

这是否意味着使用通常的属性绑定器不是一个好习惯。在这种情况下我们应该更喜欢组件绑定? 我不是故意的。应该首选使用组件值绑定,但这不是您当前的问题,对吧? 没错。我看到了这个问题,并想问。我会单独提出一个问题。 @BalusC:正如您已标记其中将有组件实例的 HashMap(RequestScoped),不会将其注入更广泛的范围(视图/会话)将导致类似的结果 - [The表达式 [.., request,] 引用的对象的范围比会话的引用托管 bean () 范围短。即使通过将请求范围 bean 作为参数传递给会话范围 bean 的操作方法来解决它,我也曾经得到过这个。 @Shirgill:不错的收获。不知道为什么我把它倒了,也许我脑子里有 CDI。已解决,谢谢!

以上是关于组件绑定与 findComponent() - 何时使用哪个?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 1.5+ 组件可选单向绑定

将一个字符串映射为一个Delphi页面控件属性名(通过FindComponent和GetPropInfo找到这个控件指针)

在 JSF 中按 ID 查找组件

@Autowired与@Resource有何区别?

@Autowired与@Resource有何区别?

Element穿梭框Transfer与进度条组件绑定