【发布时间】:2012-03-21 00:47:48
【问题描述】:
在下面的示例中,我能否以某种方式告诉 JSF <f:attribute> 适用于某些特定组件,就像我可以在 <f:convertNumber for="..."> 和 <f:validator for="..."> 中使用 for="..." 一样?
<mytags:myCcInputWithValueHolder id="myparent" item="#{myBean.myDouble}" >
<f:convertNumber minFractionDigits="2" for="myinput"/>
<f:validator validatorId="bindableDoubleRangeValidator" for="myinput"/>
<f:attribute name="minimum" value="#{30.00}"/>
<f:attribute name="maximum" value="#{39.99}"/>
</mytags:myCcInputWithValueHolder>
背景:
在BalusC's solution to a JSF issue 之后,我使用了自定义验证器。为了给验证器提供一些参数,使用了<f:attribute>。
接下来,当使用带有EditableValueHolder 的复合组件时,我可以(事实上:必须)将验证器分配给实际的h:inputText。但是我没有对f:attributes 做同样的事情,所以这些被添加到调用父组件中。例如:
<composite:attribute name="item" .../>
<composite:editableValueHolder name="myinput" targets="myinputtext"/>
:
<h:inputText id="myinputtext" value="#{cc.attrs.item}">
<!-- <composite:insertChildren /> doesn't change anything -->
</h:inputText>
...与<f:validator for="myinput" ...> 一起使用,如本文顶部所示,将验证器绑定到myparent:myinputtext,但属性绑定到myparent。
解决方法:
documentation for <f:attribute> indeed states:
向与最近的父 UIComponent 自定义操作关联的 UIComponent 添加一个属性。
鉴于此,以下复合组件也可以按预期工作:
<composite:attribute name="item" .../>
<composite:attribute name="min" .../>
<composite:attribute name="max" .../>
:
<h:inputText id="myinput" value="#{cc.attrs.item}">
<f:convertNumber minFractionDigits="2"/>
<f:validator validatorId="bindableDoubleRangeValidator"/>
<f:attribute name="minimum" value="#{cc.attrs.min}"/>
<f:attribute name="maximum" value="#{cc.attrs.max}"/>
</h:inputText>
...与:
<mytags:myCcInputWithValidator
item="#{myBean.myDouble}" min="#{30.00}" max="#{39.99}"/>
另外,我可以轻松扩展BalusC's BindableDoubleRangeValidator 以递归到父组件中以获取值:
Object getAttribute(FacesContext c, UIComponent component, String name) {
Object result = component.getAttributes().get(name);
if (result == null && component.getParent() != null) {
result = getAttribute(c, component.getParent(), name);
}
return result;
}
仍然:有更好的解决方案吗?
【问题讨论】:
标签: java jsf-2 attributes composite-component