ui:repeat 内的 Primefaces ManyCheckbox 仅在最后一个循环中调用 setter 方法

2023-12-21

我有一个<p:selectManyCheckbox> inside <ui:repeat>,从某个对象类的列表中获取它的项目(由<ui:repeat>-变量),并且应该将所选项目保存到同一对象类的另一个列表中。但它调用了setter方法#{cartBean.setSelectedExtras}仅适用于最后一个条目(最后一次迭代<ui:repeat>).

<ui:repeat var="item" value="#{category.items}">
    <p:selectManyCheckbox id="extraCheckbox" value="#{cartBean.selectedExtras}" layout="pageDirection" converter="omnifaces.SelectItemsConverter">  
         <f:selectItems value="#{item.items5}" var="extra" itemLabel="#{extra.name}"/>
    </p:selectManyCheckbox>
</ui:repeat>

Update:我按照 BalusC 提出的方式更改了上述构造。
支持 bean 中的声明现在是:

private List<List<Item>>  selectedExtras   = new ArrayList<List<Item>>();

当我检查由第一个循环创建的复选框时<ui:repeat>并单击<p:commandButton>里面同一个<h:form>setter 方法selectedExtras不被调用。当我检查在最后一个循环中创建的复选框时<ui:repeat>并单击<p:commandButton>我得到一个例外:

javax.el.PropertyNotFoundException: /lightbox-item.xhtml @57,165 value="#{cartBean.selectedExtras[iteration.index]}": null

这个结构对我来说效果很好。

正如其中提到的展示页面 http://showcase.omnifaces.org/converters/SelectItemsConverter, the omnifaces.SelectItemsConverter默认情况下使用toString()将复杂对象表示为转换后的项目值。所以如果你没有覆盖toString()方法(因此它仍然默认为com.example.SomeClass@hashcode在每个实例化时都会改变)和#{item}托管 bean 是请求范围的,那么该列表基本上会在每个 HTTP 请求上发生变化。这将导致“验证错误:值无效”错误。

如果你添加

<p:messages autoUpdate="true" />

or

<p:growl autoUpdate="true" />

这样您就可以在 UI 中获得所有(丢失的)验证/转换消息,那么您应该已经注意到了。

为了利用omnifaces.SelectItemsConverter在最好的情况下,你应该覆盖toString()相应的方法,以便它返回复杂对象的固定且唯一的表示。例如。

@Override
public String toString() {
    return "Extra[id=" + id + "]";
}

或者,您可以将#{item}托管 bean 的范围更广,例如视图范围。


Update至于您的更新,您正在绑定所选的值all复选框组到一且相同豆属性#{cartBean.selectedExtras}。这样,每次迭代都会使用当前迭代轮次的值覆盖该属性,直到最终得到最后一次迭代的值。如果您在设置器上放置了调试断点,您就会注意到这一点。

这个不对。它们应该各自指向不同的 bean 属性。从技术上讲,你应该有一个#{item.selectedExtras}作为财产。但我认为这在你当前的设计中没有意义。更好的是使#{cartBean.selectedExtras} an List<Item[]> or Item[][]。这样你就可以根据迭代索引来设置它们,如下所示:

<ui:repeat var="item" value="#{category.items}" varStatus="iteration">
    <p:selectManyCheckbox id="extraCheckbox" value="#{cartBean.selectedExtras[iteration.index]}" layout="pageDirection" converter="omnifaces.SelectItemsConverter">  
         <f:selectItems value="#{item.items5}" var="extra" itemLabel="#{extra.name}"/>
    </p:selectManyCheckbox>
</ui:repeat>

的情况下List<Item[]>你只需要确保你预初始化selectedExtras空值的次数与存在的次数一样多#{category.items}在 bean 的(后)构造函数中。

for (Item item : category.getItems()) {
    selectedExtras.add(null);
}

的情况下Item[][],你可以满足

selectedExtras = new Item[category.getItems().size()];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ui:repeat 内的 Primefaces ManyCheckbox 仅在最后一个循环中调用 setter 方法 的相关文章

随机推荐