将EL表达式传递给复合组件 [英] Passing EL expression to composite component

查看:129
本文介绍了将EL表达式传递给复合组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们仍处于从JSF 1.2到2.0的迁移方案中,现在面临着与EL表达式中使用的c:set或ui:param变量有关的问题.

we are still in a JSF 1.2 to 2.0 migration scenario and we are now facing a problem related to c:set or ui:param variables used inside an EL expression.

这是事实.有一个按钮作为复合组件:

Here are the facts. There is a button as composite component:

<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(我们已经尝试过两种方法)在工具栏中确定的.

Now we are trying to use this button component inside a toolbar. The disabled state of the button is determined inside the toolbar using a c:set or a ui:param (we already tried both ways).

<c:set var="isButtonEnabled" value="#{backingBean.buttonEnabled}" />
or
<ui:param name="isButtonEnabled" value="#{backingBean.buttonEnabled}" />

#{isButtonEnabled}

<ctrl:button
    ...
    disabled="#{!isButtonEnabled}"
    ... />

这是我们的问题.如果我们简单地在工具栏中打印出"isButtonEnabled"的值,则它总是正确的.因此,支持bean没问题.但是,当我们尝试将此值传递给复合组件时,它不起作用. "Disabled"始终评估为false.

So here is our problem. If we simple print out the value of "isButtonEnabled" in the toolbar, it is always correct. So the backing bean is ok. But when we try to pass this value to the composite component, it is not working. "Disabled" is always evaluated to false.

当然,我们可以直接传递方法表达式(#{!backingBean.isButtonEnabled}),这将正常工作.但是在我们的场景中,启用标志的确定要复杂得多,我只是试图使示例尽可能简单.另外,此标志用于工具栏内的多个按钮,因此我们希望通过使用c:set或ui:param来保持代码的可维护性.这是错误的处理方式吗?您有什么建议?

Sure we could pass the method expression directly (#{!backingBean.isButtonEnabled}) and this will work fine. But in our scenario the determination of the enabled-flag is much more complicated and I just tried to keep the example as simple as possible. Aditionally this flag is used for multiple buttons inside the toolbar, so we wanted to keep the code maintainable by using a c:set or ui:param. Is this the wrong way to handle this? What do you recommend?

谢谢.

SlimShady

SlimShady

推荐答案

您的问题是在JSF中完成值绑定的方式.首选方法是通过调用getValueExpression("attributeName")检索填充了属性的EL表达式.然后,可以使用此EL表达式来获取或设置备用Bean中的值.由于您没有传递#{!isButtonEnabled}而是将#{cc.attrs.disabled}传递给ice:commandButton,因此绑定失败.

Your problem is the way value binding is done in JSF. The prefered way is to retrieve the EL Expression an attribute was populated with by invoking getValueExpression("attributeName"). Then this EL Expression can be used to get or set the value in the backing bean. As your not passing #{!isButtonEnabled} but #{cc.attrs.disabled} to ice:commandButton the binding fails.

我通过编写包装UIComponent来解决Primefaces的p:selectOneMenu组件的问题,该包装定义了属性wrappedValue并将该属性传递给p:selectOneMenu.然后,在该属性的获取器和设置器中,我使用getValueExpression来重新获得该属性的真实EL表达式.

I solved this for the p:selectOneMenu component of Primefaces by writing a wrapping UIComponent which defines a property wrappedValue and passed that property to the p:selectOneMenu. In the getter and setter of that property I then used getValueExpression to retieve the real EL Expression for the attribute.

<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);
    }
}

现在可以通过以下方式使用该组件:

The component can now be used the following way:

<g:rarityChooser value="#{itemSearchBean.minRarity}" />

这篇关于将EL表达式传递给复合组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆