我使用 f:attribute 标记将值表达式存储在 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 Map 中”。 这是完整规范中唯一出现的术语“ValueExpression Map”。 我如何访问该地图?
Jboss/Mojarra 实现的 UI 组件方法 getValueExpression() 中的地图
getStateHelper().get(UIComponentBase.PropertyKeys.bindings)
用于获取单值表达式。
我猜该映射是“ValueExpression Map”的超集? 我能否确定所有实现和所有继承的(标准)组件都使用该映射来存储 ValueExpressions?
谢谢。
UIComponent#getAttributes()
:看到它们全部
var attributes = component.getAttributes();
for (var entry : attributes.entrySet()) {
System.out.printf("name=%s, value=%s%n", entry.getKey(), entry.getValue());
}
但是,这并不像您期望的那样工作。它只返回静态属性。这似乎永远不会被修复/实施。另请参阅Mojarra 问题 640。不过,我确实同意 javadoc 需要进一步澄清。
我建议坚持使用预定义前缀和增量数字后缀的属性,就像您在示例中所示的那样。您可以按照以下方式收集它们:
var attributes = component.getAttributes();
var values = new ArrayList<Object>();
for (int i = 1; i < Integer.MAX_VALUE; i++) {
var name = "myId" + i;
var value = attributes.get(name);
if (value == null && component.getValueExpression(name) == null) break;
values.add(value);
}
System.out.println(values);
BalusC 给出的答案的替代方案可能是使用嵌套构面或 UIParameter 组件。可以使用 getFacets 将分面作为映射进行检索,但您可能需要在每个分面内放置一个额外的 UIOutput 来访问其值表达式。
嵌套的UIParameters 可以通过迭代子组件并检查 instanceof UIParameter
来访问。 UIParameters 具有
name
和
value
属性,因此可以轻松转换为地图。我在自定义组件中使用了参数,但我不确定示例中的标准 UIInput 对这些参数有何反应。