Передача выражения 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}" />