【发布时间】:2011-01-14 15:07:10
【问题描述】:
如何在运行时动态绑定某个组件的值? 例如,我有以下组件标签,
<h:inputText value="#{bean.someProp}" />
就我而言,“#{bean.someProp}”仅在运行时才知道。
什么是最好的实施策略?
我应该遍历组件树并以编程方式设置值绑定吗?如果是,我应该在哪个 JSF 生命周期阶段进行遍历?
【问题讨论】:
如何在运行时动态绑定某个组件的值? 例如,我有以下组件标签,
<h:inputText value="#{bean.someProp}" />
就我而言,“#{bean.someProp}”仅在运行时才知道。
什么是最好的实施策略?
我应该遍历组件树并以编程方式设置值绑定吗?如果是,我应该在哪个 JSF 生命周期阶段进行遍历?
【问题讨论】:
您可以将其绑定到Map<String, Object> 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,如果你愿意的话。
【讨论】:
#{bean.map['someProp']} 对 bean 属性(使用 setter/getter)进行读/写绑定?这会令人惊讶,因为可以使用该语法读取 setter/getter 属性。
另一种选择是您可以为您的 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}
但是,这不会保留在您想要的验证器等元数据上。但是,您可以以编程方式调用验证并自行处理。
【讨论】: