如何在p:dataTable中将参数传递给valueChangeListener?

时间:2011-12-05 08:19:15

标签: jsf jsf-2 primefaces parameter-passing valuechangelistener

我在数据表中的valueChangeListener上调用<h:selectBooleanCheckbox>。并且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,我可以将'supplier'对象以及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>

2 个答案:

答案 0 :(得分:6)

在这种特殊情况下,您可以通过以编程方式评估#{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()"

答案 1 :(得分:0)

我看到你在bean之前忘记了一个大括号({):

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

此外,由于您使用的是Primefaces,您可以使用它的组件(如果您使用版本3):http://www.primefaces.org/showcase-labs/ui/selectBooleanCheckbox.jsf

如果使用jsf 2:

,则无需使用outputText
<f:facet name="header">   
  Suppliers  
</f:facet>   

此外,没有必要使用f:facet,因为column组件有一个名为headerText的属性:

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

这种方式简单得多,不是吗?

PS:这是什么? value="supplier.supplierAccountList"否#{}?