我们仍处于JSF 1.2到2.0迁移场景中,我们现在面临与c表达式相关的问题:在EL表达式中使用的set或ui:param变量。
以下是事实。有一个按钮作为复合组件:
<cc:interface name="button" shortDescription="A button.">
...
<cc:attribute
name="disabled"
required="false"
default="false"
shortDescription="The disabled flag." />
...
</cc:interface>
<cc:implementation>
<ice:commandButton
...
disabled="#{cc.attrs.disabled}"
... />
</cc:implementation>
现在我们尝试在工具栏中使用此按钮组件。使用c:set或ui:param(我们已经尝试过两种方式)在工具栏内确定按钮的禁用状态。
<c:set var="isButtonEnabled" value="#{backingBean.buttonEnabled}" />
or
<ui:param name="isButtonEnabled" value="#{backingBean.buttonEnabled}" />
#{isButtonEnabled}
<ctrl:button
...
disabled="#{!isButtonEnabled}"
... />
所以这是我们的问题。如果我们简单地打印出&#34; isButtonEnabled&#34;的值。在工具栏中,它始终是正确的。所以支持bean是好的。但是当我们尝试将此值传递给复合组件时,它无法正常工作。 &#34;禁用&#34;始终被评估为false。
当然我们可以直接传递方法表达式(#{!backingBean.isButtonEnabled}),这样可以正常工作。但在我们的场景中,启用标志的确定要复杂得多,我只是尽量保持示例尽可能简单。此类标志用于工具栏内的多个按钮,因此我们希望通过使用c:set或ui:param来保持代码的可维护性。这是处理这个问题的错误方法吗?你推荐什么?
提前致谢。
SlimShady
答案 0 :(得分:3)
您的问题是在JSF中完成值绑定的方式。首选方法是检索EL表达式,通过调用getValueExpression("attributeName")
填充属性。然后,此EL表达式可用于获取或设置辅助bean中的值。由于您未将#{!isButtonEnabled}
但#{cc.attrs.disabled}
传递给ice:commandButton
,因此绑定失败。
我通过编写一个定义属性p:selectOneMenu
的包UIComponent
并将该属性传递给wrappedValue
,为Primefaces的p:selectOneMenu
组件解决了这个问题。在该属性的getter和setter中,我使用getValueExpression
来恢复该属性的真实EL表达式。
<composite:interface componentType="de.gw2tome.component.valuewrapper">
<composite:attribute name="value" type="de.gw2tome.models.Rarity"
required="true" />
</composite:interface>
<composite:implementation>
<p:selectOneMenu value="#{cc.wrappedValue}"/>
...
</composite:implementation>
@FacesComponent("de.gw2tome.component.valuewrapper")
public class ValueWrapper extends UINamingContainer {
public void setWrappedValue(Object wrappedValue) {
ValueExpression expr = getValueExpression("value");
ELContext ctx = getFacesContext().getELContext();
expr.setValue(ctx, wrappedValue);
}
public Object getWrappedValue() {
ValueExpression expr = getValueExpression("value");
ELContext ctx = getFacesContext().getELContext();
return expr.getValue(ctx);
}
}
现在可以通过以下方式使用该组件:
<g:rarityChooser value="#{itemSearchBean.minRarity}" />