我偶然发现了一个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时,我在设置器中的日志记录消息显示:
- 当支持 bean 的范围设置为查看两个选定的数字时,在更新模型值阶段设置正确
- 当 backing bean 的范围设置为Request only the selected number from the top table 正确设置时,selectedDivisor字段(与底部p:dataTable链接)的设置器携带值 0 (或 null 在其他我用不同的类尝试过的例子)。
请注意,在这个简单的示例中没有业务逻辑需要从底部的p:dataTable中选择一个数字——这只是我在真实上下文中遇到的同一问题的缩小版本。任何人都可以解释 JSF 生命周期中导致在视图为RequestScoped(而不是成功的ViewScoped)时未正确设置底部表格选定值的步骤吗?