Primefaces ManyCheckbox里面ui:重复调用setter方法只用于最后一个循环 [英] Primefaces ManyCheckbox inside ui:repeat calls setter method only for last loop

查看:291
本文介绍了Primefaces ManyCheckbox里面ui:重复调用setter方法只用于最后一个循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在< ui:repeat> 中有一个< p:selectManyCheckbox> 一个特定对象类的列表(由< ui:repeat> -variable提供),并且应该将所选项目保存到同一对象类的另一个列表中。但它只为最后一个条目调用setter方法#{cartBean.setSelectedExtras} (最后一次迭代< ui:repeat> )。

I have a <p:selectManyCheckbox> inside <ui:repeat>, getting it's items from a List of a certain Object Class (provided by <ui:repeat>-variable) and is supposed to save the chosen items into another List of the same Object Class. But it calls the setter method #{cartBean.setSelectedExtras} only for the last entry (last iteration of <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中的声明:

Update: I changed the above construct just the way BalusC proposed.
Declaration in backing bean is now:

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

当我检查由< ui的第一个循环创建的复选框:repeat> ,然后点击同一个< h:form> < p:commandButton> c $ c> selectedExtras 的setter方法未被调用。当我检查在< ui:repeat> 的最后一个循环中创建的复选框,然后点击< p:commandButton> 我得到一个异常:

When I check checkboxes that were created by the first loops of <ui:repeat> and click the <p:commandButton> inside the same <h:form> the setter method of selectedExtras is not called. When I check the checkboxes created in the last loop of <ui:repeat> and click the <p:commandButton> I get an Exception:

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


推荐答案

正如其他人所提到的展示页面 omnifaces.SelectItemsConverter 默认使用 toString()该复杂对象作为转换项目值。所以如果你没有重写 toString()方法(所以它仍然默认为 com.example.SomeClass@hashcode 其在每个实例化时改变),并且#{item} 托管bean是请求范围的,则该列表基本上将在每个HTTP请求上改变。这将导致验证错误:值无效错误。

As mentioned in among others the showcase page, the omnifaces.SelectItemsConverter uses by default the toString() representation of the complex object as converted item value. So if you didn't override the toString() method (so that it still defaults to com.example.SomeClass@hashcode which changes on every instantiation) and the #{item} managed bean is request scoped, then the list would basically be changing on every HTTP request. This would cause a "Validation Error: Value is not valid" error.

如果您添加

<p:messages autoUpdate="true" />

<p:growl autoUpdate="true" />

,以便在UI中获取所有(缺少)验证/转换消息,

so that you get all (missing) validation/conversion messages in the UI, then you should have noticed it.

为了充分利用 omnifaces.SelectItemsConverter ,您应该覆盖 toString()方法,以便它返回复杂对象的固定且唯一的表示。例如

In order to utilize the omnifaces.SelectItemsConverter at its best, you should override the toString() method accordingly so that it returns a fixed and unique representation of the complex object. E.g.

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

或者,您可以将#{item}

Alternatively, you could put the #{item} managed bean in a broader scope, such as the view scope.

更新关于您的更新,您将选中的所有复选框组的选择值绑定到同一个 bean属性#{cartBean.selectedExtras } 。这样,每次迭代都会使用当前迭代循环中的值覆盖该属性,直到最后一次迭代的值结束。如果你在设置器上放了一个调试断点,你会注意到的。

Update as to your update, you're binding the selected values of all checkboxgroups to one and same bean property #{cartBean.selectedExtras}. This way every iteration overrides the property with the values from the current iteration round as long as until you end up with the values of the last iteration. If you've placed a debug breakpoint on the setter, you'd have noticed that.

这是不对的。他们应该指向一个不同的bean属性。从技术上讲,你应该有一个#{item.selectedExtras} 作为属性。但我认为这在当前的设计没有意义。最好是让#{cartBean.selectedExtras} 列表< Item []> Item [] [] 。这样,您可以根据迭代索引设置如下:

This is not right. They should each point to a different bean property. Technically, you should have a #{item.selectedExtras} as property. But I think that this makes no sense in your current design. Better would be to make the #{cartBean.selectedExtras} an List<Item[]> or Item[][]. This way you can get them to set based on the iteration index as follows:

<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>

列表您只需要确保您预先初始化 selectedExtras 与nulls的次数与#{category.items}

In case of List<Item[]> you only need to make sure that you preinitialize selectedExtras with nulls as many times as there are #{category.items} in bean's (post)constructor.

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

code>,可以满足

In case of Item[][], you can suffice with

selectedExtras = new Item[category.getItems().size()];

这篇关于Primefaces ManyCheckbox里面ui:重复调用setter方法只用于最后一个循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆