Как передать параметр в valueChangeListener в p: dataTable?

Я вызываю valueChangeListener на <h:selectBooleanCheckbox>, который находится внутри dataTable. и этот dataTable снова находится внутри другого (внешнего) dataTable. В методе valueChangeListener мне нужен объект экземпляра внешнего dataTable. Есть ли способ получить объект внешнего экземпляра dataTable?

EX:

<h:panelGroup id="panelId">
    <p:dataTable id="outerDatatable"
                 var="supplier"
                 value="bean.supplierList">

        <p:column>
            <f:facet name="header">
                <h:outputText value="Suppliers" />
            </f:facet>
            <h:outputText value="#{supplier.name}" />
        </p:column>

        <p:column>
            <p:dataTable id="innerDataTable"
                         var="supplierAccount"
                         value="supplier.supplierAccountList">

                <p:column>
                    <h:selectBooleanCheckbox id="booleanBoxId"
                                             value="#{supplierAccount.supported}"
                                             valueChangeListener="#bean.checkBoxListener}"
                                             immediate="true"
                                             onchange="this.form.submit();"/>
                </p:column>
            </p:dataTable>
        </p:column>
    </p:dataTable>
</h:panelGroup>

Я нашел следующее решение: я использовал прослушиватель <p:ajax> вместо valueChangeListener, и я мог передать объект поставщика, а также объект supplierAccount этому методу прослушивателя. Мы можем передать любое количество пользовательских объектов слушателю <p:ajax>.

<p:column>
    <h:selectBooleanCheckbox id="booleanBoxId"
                             value="#{supplierAccount.supported}"
                             immediate="true">
    </h:selectBooleanCheckbox>

    <p:ajax listener="#{bean.myListenerMethod(supplier,supplierAccount)}"
            update=":formName:panelId"/>
</p:column>

person Bosco    schedule 05.12.2011    source источник


Ответы (2)


В этом конкретном случае вы можете получить его, оценив #{supplier} программно:

public void checkBoxListener(ValueChangeEvent event) {
    FacesContext context = FacesContext.getCurrentInstance();
    Supplier supplier = context.getApplication().evaluateExpressionGet(context, "#{supplier}", Supplier.class);
    // ...
}

Однако это просто уродливо, вы синхронно отправляете всю форму onchange="submit()". Я рекомендую добавить для этого ajax.

<h:selectBooleanCheckbox value="#{supplierAccount.supported}">
    <f:ajax listener="#{bean.checkBoxListener}" render="???" />
</h:selectBooleanCheckbox>

(атрибут render зависит от вас)

с участием

public void checkBoxListener(AjaxBehavior event) {
    Boolean value = (Boolean) ((UIInput) event.getComponent()).getValue();
    FacesContext context = FacesContext.getCurrentInstance();
    Supplier supplier = context.getApplication().evaluateExpressionGet(context, "#{supplier}", Supplier.class);
    // ...
}

Или, если ваша среда поддерживает EL 2.2 и, таким образом, указывает аргументы метода в EL:

<h:selectBooleanCheckbox value="#{supplierAccount.supported}">
    <f:ajax listener="#{bean.checkBoxListener(component, supplier)}" render="???" />
</h:selectBooleanCheckbox>
public void checkBoxListener(UISelectBoolean checkbox, Supplier supplier) {
    boolean selected = checkbox.isSelected();
    // ...
}

Смотрите также:


Не связанный с конкретной проблемой, например с использованием onchange="submit()", может быть полезно знать, что onchange не работает должным образом для флажков в IE6/7. Он срабатывает только при каждом втором клике. Вместо этого вы хотите использовать onclick="submit()".

person BalusC    schedule 05.12.2011

Я вижу, что вы забыли фигурную скобку ({) непосредственно перед bean:

valueChangeListener="#{bean.checkBoxListener}" immediate="true" 

Кроме того, поскольку вы используете Primefaces, вы можете использовать его компоненты (если вы используете версию 3): http://www.primefaces.org/showcase-labs/ui/selectBooleanCheckbox.jsf

Нет необходимости использовать outputText, если вы используете jsf 2:

<f:facet name="header">   
  Suppliers  
</f:facet>   

Также нет необходимости использовать f:facet, потому что компонент column имеет атрибут с именем headerText:

<p:column headerText="Suppliers">
    #{supplier.name}"
</p:column>

Так намного проще, не так ли?

ПС: что это? value="supplier.supplierAccountList" Нет #{ }?

person spauny    schedule 05.12.2011
comment
спасибо за ответ .. я недавно услышал об атрибуте 'headerText', но мне придется использовать ‹facet›n e способами в качестве его общего формата, используемого в моем проекте. О value=supplier.supplierAccountList его значение=#{supplier.supplierAccountList} только в моем коде. пропустил фигурные скобки при копировании кода сюда. - person Bosco; 05.12.2011
comment
Диалоги @amruta, такие как спасибо за .., привет .. и т. д., формальности воспринимаются не очень хорошо. на самом деле они считаются спамом. - person Chani; 15.12.2011
comment
@drunkMonk Пусть человек поблагодарит :) Как минимум hello действительно спам - person spauny; 15.12.2011