Передача выражения EL в составной компонент

Мы все еще находимся в сценарии миграции JSF с 1.2 на 2.0, и сейчас мы сталкиваемся с проблемой, связанной с переменными c:set или ui:param, используемыми внутри выражения EL.

Вот факты. В качестве составного компонента есть кнопка:

<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>

Теперь мы пытаемся использовать этот компонент кнопки внутри панели инструментов. Отключенное состояние кнопки определяется внутри панели инструментов с помощью a c:set или ui:param (мы уже пробовали оба способа).

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

#{isButtonEnabled}

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

Итак, вот наша проблема. Если мы просто распечатаем значение "isButtonEnabled" на панели инструментов, это всегда правильно. Так что с бобом все в порядке. Но когда мы пытаемся передать это значение составному компоненту, оно не работает. "Отключено" всегда оценивается как ложное.

Конечно, мы можем передать выражение метода напрямую (#{! BackingBean.isButtonEnabled}), и это будет работать нормально. Но в нашем сценарии определение флажка enabled намного сложнее, и я просто попытался сделать пример как можно более простым. Кроме того, этот флаг используется для нескольких кнопок на панели инструментов, поэтому мы хотели сохранить код поддерживаемым, используя a c:set или ui:param. Это неправильный способ справиться с этим? Что вы порекомендуете?

Заранее спасибо.

Слим Шейди

1 ответ

Ваша проблема заключается в способе привязки значений в JSF. Предпочтительным способом является получение выражения EL, которым был заполнен атрибут, путем вызова getValueExpression("attributeName"), Затем это выражение EL можно использовать для получения или установки значения в компоненте поддержки. Как ваш не проходя #{!isButtonEnabled} но #{cc.attrs.disabled} в ice:commandButton привязка не удалась.

Я решил это для p:selectOneMenu компонент Primefaces, написав упаковку UIComponent который определяет свойство wrappedValue и передал это свойство p:selectOneMenu, В получателе и установщике этого свойства я тогда использовал 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}" />
Другие вопросы по тегам