我在<p:selectManyCheckbox>
内有<ui:repeat>
,从某个对象类的列表中获取它的项目(由<ui:repeat>
- 变量提供)并且应该将所选项目保存到另一个相同对象类的列表。但它仅针对最后一个条目(#{cartBean.setSelectedExtras}
的最后一次迭代)调用setter方法<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>
更新 我改变了上述结构,就像BalusC提出的那样 支持bean的声明现在是:
private List<List<Item>> selectedExtras = new ArrayList<List<Item>>();
当我选中由<ui:repeat>
的第一个循环创建的复选框并单击同一<p:commandButton>
内的<h:form>
时,不会调用selectedExtras
的setter方法。当我检查在<ui:repeat>
的最后一个循环中创建的复选框并单击<p:commandButton>
时,我得到例外:
javax.el.PropertyNotFoundException: /lightbox-item.xhtml @57,165 value="#{cartBean.selectedExtras[iteration.index]}": null
答案 0 :(得分:2)
这个结构适合我。
正如其他the showcase page中所提到的,omnifaces.SelectItemsConverter
默认使用复杂对象的toString()
表示作为转换项值。因此,如果您没有覆盖toString()
方法(因此它仍然默认为com.example.SomeClass@hashcode
在每个实例化时发生更改)并且#{item}
托管bean是请求范围的,那么列表基本上会改变每个HTTP请求。这将导致“验证错误:值无效”错误。
如果你添加
<p:messages autoUpdate="true" />
或
<p:growl autoUpdate="true" />
这样你就可以在UI中获得所有(缺失的)验证/转换消息,那么你应该注意到它。
为了最好地利用omnifaces.SelectItemsConverter
,您应该相应地覆盖toString()
方法,以便它返回复杂对象的固定且唯一的表示。 E.g。
@Override
public String toString() {
return "Extra[id=" + id + "]";
}
或者,您可以将#{item}
托管bean放在更广泛的范围内,例如视图范围。
更新,您将所有复选框组的选定值绑定到同一个 bean属性{{1} }。这样,每次迭代都会使用当前迭代轮次中的值覆盖属性,直到您最终获得最后一次迭代的值。如果您在setter上放置了一个调试断点,那么您已经注意到了。
这是不对的。它们应该指向不同的bean属性。从技术上讲,您应该拥有#{cartBean.selectedExtras}
作为财产。但我认为这在你目前的设计中毫无意义。最好是将#{item.selectedExtras}
设为#{cartBean.selectedExtras}
或List<Item[]>
。这样您就可以根据迭代索引设置它们,如下所示:
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[]>
初始化为空值的次数与bean的(post)构造函数中的selectedExtras
一样多。
#{category.items}
如果是for (Item item : category.getItems()) {
selectedExtras.add(null);
}
,则可以使用
Item[][]