关于jsf:如何将参数传递给p:dataTable中的valueChangeListener?

How to pass parameter to valueChangeListener in p:dataTable?

我在数据表内的 <h:selectBooleanCheckbox> 上调用 valueChangeListener。并且该数据表再次位于另一个(外部)数据表内。在 valueChangeListener 方法中,我想要外部数据表的实例对象。有没有办法获取外部dataTable实例的对象?

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<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,并且我可以将" vendor"对象以及 supplierAccount 对象传递给此侦听器方法。我们可以将任意数量的自定义对象传递给 <p:ajax> 侦听器。

1
2
3
4
5
6
7
8
9
<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>

在这种特殊情况下,您可以通过以编程方式评估 #{supplier} 来获得它:

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

然而,这实在是太丑了,您正在通过 onchange="submit()" 同步提交整个表单。我建议为此投入一些ajax。

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

(render 属性由您决定)

1
2
3
4
5
6
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 中指定方法参数:

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

也可以看看:

  • 何时使用 valueChangeListener 或 f:ajax 侦听器?

与具体问题无关,至于使用 onchange="submit()",知道 onchange 对 IE6/7 中的复选框没有按预期工作可能很有用。它只会在每 2 次点击时触发。你宁愿使用 onclick="submit()" 代替。


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

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

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

如果你使用 jsf 2 就没有必要使用 outputText:

1
2
3
<f:facet name="header">  
  Suppliers  
</f:facet>

也没有必要使用 f:facet 因为 column 组件有一个名为 headerText:

的属性

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

那样就简单多了,不是吗?

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