2

http://www.primefaces.org/showcase/ui/pprSelect.jsfに似た sth を実現したいのですが、ダブルコンボのコレクションが必要なので、ui:repeatでラップしました

ダブルコンボのコレクションのどの要素が変更され、何をリロードする必要があるかをバックエンドで確認する必要があります。通信には例のようにp:ajaxが使用されますが、AjaxBehaviorEventは要素のインデックスのアイデアをもたらしません(つまり、ui:repeatによって生成されたダブルコンボ要素のインデックスを意味します)

私のクライアントコード、アイデアはajax イベントが発生するたびにbean:selectedIndexを更新することです ( selectOneMenuの値の変更時)、bean:selectedIndexの値は変更されたselectOneMenuのインデックスとして設定されます

private List<State> productStates
private int selectedIndex;
private List<Group> groups;
private Map<Integer, Collection<Device>> availableDevicesMap;
<ui:repeat var="state" value="#{bean.productStates}" varStatus="iter">

    <p:selectOneMenu id="devGroup" value="#{state.group}">  
        <f:selectItems value="#{bean.groups}"  />  
            <p:ajax  update="refreshable"  process="devGroup, @this"  listener="#{bean.refreshDevicesForState}" >
                    <f:setPropertyActionListener target="#{bean.selectedIndex}" value="#{iter.index}"/>
            </p:ajax>                                    
    </p:selectOneMenu>

    <!-- THIS WILL BE UPDATED -->
    <h:panelGroup id="refreshable">
            <p:selectManyButton  id="devices" value="#{state.devices}" >  
                <f:selectItems value="#{bean.availableDevicesMap[status.index]}"   />  
            </p:selectManyButton> 
    </h:panelGroup>
</ui:repeat>

期待どおりに動作しないバックエンド。setPropertyActionListenerが呼び出されず、selectOneMenuコンポーネントが選択されたグループを値として取得していない

public refreshDevicesForState(AjaxBehaviorEvent e) {
        SelectOneMenu menu = (SelectOneMenu)e.getComponent();
    // this value is not as selected on frontend
        Group group = (Group)menu.getValue();

    // selectedIndex will not be set, so I assume that setPropertyActionListener didn't invoked
    availableDevicesMap.put(selectedIndex, group.getDevices());
}

私は動作する以下のコードでも試しましたが、私の意見では醜いです

// id will be grandpaId:parentId:index:myId 
String selectedIndex = IdHelper.getIdPart(e.getComponent().getClientId(), -2);
State state = productStates.get(Integer.parseInt(selectedIndex));

私はjsfリファレンス実装としてglassfishとMojarraで最新のprimefacesを使用しています

助けてくれてありがとう

より一般的な意味で:

バッキングされた Bean にオブジェクトのリストがあります。たとえば、車としましょう

List<Car> cars

frontent では、それらを反復処理して、すべての車の選択したブランド選択したモデルの組み合わせを作成します。ユーザーが 4 台目の車のブランドを選択すると、4 台目の車が変更されることをバックエンドで知りたいので、この 1 台の車で利用可能なモデルのリストをリロードします

 <ui:repeat var="state" value="#{bean.cars}" >
    <p:selectOneMenu id="brands"/>// select brand

    <p:selectOneMenu "models"/>// show available models depends on selected brand
 </ui:repeat>

JSFの世界でそれを正しく処理するには?

4

1 に答える 1

2

私の最初の提案は、グループにコンバーターを使用することです。SelectOneMenu はカスタム クラスを設定できません。コンバーターを使用する必要があります。(例はオートコンプリートにあります: http://www.primefaces.org/showcase/ui/autoCompletePojo.jsf )

次に、Bean ハンドラーのproductStates変数には、(selectOneMenus の) 選択された値が既に含まれています。イベントからアクセスするよりも簡単に使用できます。

selectOneMenus の値が State に依存する場合は、これを変更する必要があります。

<f:selectItems value="#{bean.groups}"  />

どのグループ値を表示するかを表現できるようにします。

(Eclipse デバッグなしで) デバッグする場合は、次のようなメッセージを使用できます。

これを xhtml に追加します。

<p:growl id="msgs" showDetail="true"/>

そして豆で:

public refreshDevicesForState(AjaxBehaviorEvent e) {

 ...
 FacesMessage msg = new FacesMessage("Selected", "any debug info" + productStates.get(0).getGroup());  
 FacesContext.getCurrentInstance().addMessage(null, msg);  

}

あなたの改造に従って、私は私の答えを修正しました。私はこのようにします:

xhtml:

<ui:repeat var="state" value="#{bean.productStates}" varStatus="iter">

 <p:selectOneMenu id="devGroup#{iter.index}" value="#{state.group}"
        valueChangeListener="#{bean.updateSubProperty}" immediate="true">  
  <f:selectItems value="#{bean.groups}"  />  
  <f:attribute name="index" value="#{iter.index}" />
 </p:selectOneMenu>

 <p:selectOneMenu id="subDevGroup#{iter.index}">
  ...
 </p:selectOneMenu>
</ui:repeat>

豆:

 public void updateSubProperty(ValueChangeEvent vce) {
  String index = vce.getComponent().getAttributes().get("index").toString();
  int i = Integer.parseInt(index); //this is the index of the selected selectOneMenu
  ///...

  //update sub selectOneMenu
  RequestContext.getCurrentInstance().update("subDevGroup" + index);
 }
于 2013-05-24T10:07:24.220 に答える