2

特定のオブジェクト クラス (-variable によって提供される) のリストからアイテムを取得し<p:selectManyCheckbox>、選択したアイテムを同じオブジェクト クラスの別のリストに保存することになっています。ただし、最後のエントリ (の最後の繰り返し) に対してのみセッター メソッドを呼び出します。<ui:repeat><ui:repeat>#{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>

更新: BalusC が提案した方法で上記の構成を変更しました。
バッキング Bean の宣言は次のようになりました。

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

の最初のループによって作成されたチェックボックスをチェックして、同じ内部<ui:repeat>をクリックすると、のセッターメソッドは呼び出されません。の最後のループで作成されたチェックボックスをオンにしてクリックすると、例外が発生します。 <p:commandButton><h:form>selectedExtras<ui:repeat><p:commandButton>

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

1 に答える 1

2

この構成は私にとってはうまく機能します。

特にショーケースページで述べたように、omnifaces.SelectItemsConverterデフォルトtoString()では複合オブジェクトの表現を変換されたアイテム値として使用します。したがって、toString()メソッドをオーバーライドせず (インスタンス化のたびにデフォルトでcom.example.SomeClass@hashcodeどの変更が行われるか)、#{item}マネージド Bean がリクエスト スコープである場合、リストは基本的にすべての HTTP リクエストで変更されます。これにより、「検証エラー: 値が無効です」というエラーが発生します。

追加すると

<p:messages autoUpdate="true" />

また

<p:growl autoUpdate="true" />

UI ですべての (不足している) 検証/変換メッセージを取得できるようにするには、それに気付くはずです。

omnifaces.SelectItemsConverterを最大限に活用するにtoString()は、複雑なオブジェクトの固定された一意の表現を返すように、メソッドを適宜オーバーライドする必要があります。例えば

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

または、#{item}マネージド Bean をより広いスコープ (ビュー スコープなど) に配置することもできます。


あなたの更新に関して更新すると、すべてのチェックボックスグループの選択された値1の同じBeanプロパティにバインドしています#{cartBean.selectedExtras}。このようにして、最後の反復の値で終了するまで、すべての反復が現在の反復ラウンドの値でプロパティをオーバーライドします。セッターにデバッグ ブレークポイントを配置した場合は、それに気付くでしょう。

これは正しくないです。それぞれが異なる Bean プロパティを指す必要があります。技術的には、#{item.selectedExtras}as プロパティが必要です。しかし、これは現在の設計では意味がないと思います。またはを作成#{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>

Beanの(ポスト)コンストラクターにある回数だけnullで事前に初期化List<Item[]>することを確認するだけでよい場合。selectedExtras#{category.items}

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

の場合Item[][]、あなたはで十分です

selectedExtras = new Item[category.getItems().size()];
于 2012-10-30T22:05:25.100 に答える