1

我偶然发现了一个JSF / PrimeFaces问题,尽管我设法通过更改支持 bean 的范围来使其工作,但我仍然想了解为什么它在第一种情况下失败。因此,这是一个重现该行为的缩小示例:

我们有一个非常简单的xhtml页面,它在一个表单中显示两个p:dataTables,一个在另一个之下。顶部p:dataTable显示数字,第二个显示除数。所以我们有一个经典的主从视图。一个按钮允许我们更新页面,因此当从顶部表格中选择一个新数字时,我们可以在底部表格中查看其除数:

<h:form id="NUMBERS-form">
    <p:dataTable id="dt1" var="item" value="#{numbersController.divisorSets}"
                 rowKey="#{item}" rows="10" selection="#{numbersController.selectedDivisorSet}"
                 selectionMode="single">
        <p:column>
            #{item}
        </p:column>
    </p:dataTable>

    <p:dataTable id="dt2" var="item" value="#{numbersController.divisors}"
                 rowKey="#{item}" rows="10" selection="#{numbersController.selectedDivisor}"
                 selectionMode="single">
        <p:column id>
            #{item}
        </p:column>
    </p:dataTable>
    <p:commandButton id="Update"     ajax="true" update=":NUMBERS-form"
                     action="#{numbersController.foo}" value="update"/>
</h:form>

支持 bean 定义了两个只读集合:一个用于DivisorSets(即我们要查找其除数的数字),另一个用于当前所选数字的除数。它还有两个字段和属性获取器/设置器,用于当前选定的数字和该数字的当前选定除数:

@ManagedBean
@ViewScoped // if this is toggled to @RequestScoped it stops working
public class NumbersController implements Serializable {
    private static final Logger l = Logger.getLogger(NumbersController.class.getName());

    public List<DivisorSet> getDivisorSets() {
        List<DivisorSet> retValue = new ArrayList<DivisorSet>();
        for (int i = 10 ; i < 20 ; i++)
            retValue.add( new DivisorSet(i) );
        return retValue;
    }

    public List<Integer> getDivisors() {
        if (selectedDivisorSet != null)
            return selectedDivisorSet.getDivisors();
        else return null;
    }

    private DivisorSet    selectedDivisorSet;
    // getter and setter ...

    private Integer   selectedDivisor;
    // getter and setter ...

    public String foo() { return null; }
}

首次加载页面时,仅填充顶部的p:dataTable 。当顶部表格的一行被选中并按下p:commandButton时,该数字的除数将在底部p:dataTable上获取。到目前为止,一切都很好。问题来了:当从顶部表中选择一行并且从底部表中选择一行并按下p:commandButton时,我在设置器中的日志记录消息显示:

  1. 当支持 bean 的范围设置为查看两个选定的数字时,在更新模型值阶段设置正确
  2. 当 backing bean 的范围设置为Request only the selected number from the top table 正确设置时,selectedDivisor字段(与底部p:dataTable链接)的设置器携带值 0 (或 null 在其他我用不同的类尝试过的例子)。

请注意,在这个简单的示例中没有业务逻辑需要从底部的p:dataTable中选择一个数字——这只是我在真实上下文中遇到的同一问题的缩小版本。任何人都可以解释 JSF 生命周期中导致在视图为RequestScoped(而不是成功的ViewScoped)时未正确设置底部表格选定值的步骤吗?

4

0 回答 0