2011-10-07 25 views
4

我存储值表达式的JSF组件与F的“ValueExpression地图”:属性标记,例如:JSF组件

<h:inputText ...> 
    <f:attribute name="myId1" value="#{bean.prop1}" /> 
    <f:attribute name="myId2" value="#{bean.prop2}" /> 
    <f:attribute name="myId3" value="#{bean.prop3}" /> 
</h:inputText> 

有没有以编程方式访问所有这些值表达式的方法吗? (不知道名称myId1,myId2,...)

JSF 2.1规范的第9.4.2节说,这些值存储在“组件的ValueExpression映射表”中。 这是整个规范中唯一出现的术语“ValueExpression Map”。 如何访问该地图?

在UIComponent的方法getValueExpression()中的的Jboss /钻嘴鱼科执行地图

getStateHelper().get(UIComponentBase.PropertyKeys.bindings) 

的用于获得一个单一值表达式。

我猜那个地图是“ValueExpression Map”的超集? 我可以确定所有实现和所有继承(标准)组件都使用该映射来存储ValueExpressions吗?

谢谢。

回答

2

理论你应该能够通过UIComponent#getAttributes()一饱眼福:

Map<String, Object> attributes = component.getAttributes(); 

for (Map.Entry<String, Object> entry : attributes.entrySet()) { 
    System.out.printf("name=%s, value=%s%n", entry.getKey(), entry.getValue()); 
} 

但是,不工作,你所希望的方式。它只返回静态属性。这似乎不会被固定/实施。另见JSF issue 636。我建议坚持使用预先定义的前缀和增量数字后缀的属性,就像您在示例中介绍的那样。这也是我一直用来从组件传递额外信息到自定义验证器和转换器的原因。你可以只收集它们如下:

Map<String, Object> attributes = component.getAttributes(); 
List<Object> values = new ArrayList<Object>(); 

for (int i = 1; i < Integer.MAX_VALUE; i++) { 
    Object value = attributes.get("myId" + i); 
    if (value == null) break; 
    values.add(value); 
} 

System.out.println(values); 
+0

我不认为该规范允许在属性映射中存储像上面那样的f:属性值。 Mojarra没有。 你上面测试了你的代码吗?你正在使用哪个实现? – Thomas

+0

咦?为什么你这么想?所有组件的属性都在那里,参见链接的javadoc:*“返回一个表示与此UIComponent关联的属性(和属性,见下文)的可变Map,由属性名称(必须是String)键入”*“。这从JSF 1.0开始就是这样工作的。 – BalusC

+0

9.4.2的规范说:“...对参数值调用isLiteralText()方法,如果返回true,则将该值存储在上面派生的名称下的组件属性Map中;如果返回false,则存储在上面派生的名称下的组件的ValueExpression Map中的ValueExpression。“ 此外,我已经testet它和属性映射不包含它们。 – Thomas

1

BalusC给出的可能是使用嵌套面或UIParameter组件答案的替代品。方面可以使用getFacets作为地图检索,但您可能需要在每个方面内部放置额外的UIOutput以访问其值表达式。

嵌套UIParameters可以通过遍历子组件和检查instanceof UIParameter来访问。 UIParameters具有namevalue属性,因此可以轻松转换为地图。

我在自定义组件中使用了参数,但我不确定标准UIInput如何在您的示例中对这些参数做出反应。

0

BalusC是对的。 UIComponent#getAttributes()。get(name)从两个地方获取值 - 首先从属性映射中获取值,然后从“值表达式映射”中找到。为了增加一些价值,你必须调用UIComponent#setValueExpression(name,ValueExpression)。如果值是字面值,则将其存储到属性映射中,否则将存储到“值表达式映射”中。一切都很好。