JSF组件的动态值绑定

Posted

技术标签:

【中文标题】JSF组件的动态值绑定【英文标题】:Dynamic value binding of JSF component 【发布时间】:2011-01-14 15:07:10 【问题描述】:

如何在运行时动态绑定某个组件的值? 例如,我有以下组件标签,

<h:inputText value="#bean.someProp" />

就我而言,“#bean.someProp”仅在运行时才知道。

什么是最好的实施策略?

我应该遍历组件树并以编程方式设置值绑定吗?如果是,我应该在哪个 JSF 生命周期阶段进行遍历?

【问题讨论】:

【参考方案1】:

您可以将其绑定到Map&lt;String, Object&gt; bean 属性,其中String 键或多或少是动态属性名称。您可以通过以下方式访问 EL 中的地图值:

<h:inputText value="#bean.map.someProp" />

<h:inputText value="#bean.map['someProp']" />

这甚至可以更动态地完成,其中someVar 实际上解析为"someProp"String 值:

<h:inputText value="#bean.map[someVar]" />

你只需要保证Map是在bean初始化时创建的,否则JSF不能访问映射值。 EL 即不会为您预先创建“嵌套属性”。因此,例如直接实例化:

public class Bean 
    private Map<String, Object> map = new HashMap<String, Object>();

.. 或者在构造函数中,或者@PostConstruct,如果你愿意的话。

【讨论】:

好的,我明白你的意思了。这是一个好主意,除了我将丢失在我的实体的注释中定义的所有元数据。这也意味着失去使用 (来自 SEAM 的休眠验证标签)和所有其他依赖于注释元数据的基础设施的优势。仅供参考,我这样做是为了制作一个实现“裸对象”模式的框架(一个参考实现是nakedobjects.org)。基本上它检查一个实体并自动构建相关的表和表单(在本例中为组件树)。 Urm,... 再想一想,使用这种方法我不必丢失所有注释元数据。我会试试这个并告诉你。 这是我目前的做法。通过这样做,我失去了 的优势,不得不在其他地方重新实现验证。不过这很简单,只需调用 hibernateValidator.validate(bean)。 这是否意味着不可能使用#bean.map['someProp'] 对 bean 属性(使用 setter/getter)进行读/写绑定?这会令人惊讶,因为可以使用该语法读取 setter/getter 属性。【参考方案2】:

另一种选择是您可以为您的 bean 添加一个抽象层。

public String getDynamicProp() 
   ...Code to determine and return the correct property based on the meta-data...


public void setDynamicProp(String input) 
   ...Code to determine and return the correct property based on the meta-data...

然后你可以将你的 JSF 直接绑定到动态属性:

#bean.dynamicProp

但是,这不会保留在您想要的验证器等元数据上。但是,您可以以编程方式调用验证并自行处理。

【讨论】:

以上是关于JSF组件的动态值绑定的主要内容,如果未能解决你的问题,请参考以下文章

在同一个组件中使用 JSF 绑定 + 验证器显示消息两次

是否可以在 JSF 中实现组件的动态树?

JSF 组件绑定 - 一些混乱

没有 bean 属性的 JSF 组件绑定

如何在 JSF 中正确使用组件绑定? (会话范围 bean 中的请求范围组件)

如何将 JSF 组件绑定到支持 bean 属性