0

JSF2(MyFaces 2.1)とCDI(Weld)を使用して、列挙型で満たされたselectOneMenuを使用して、2番目のselectOneMenu(コード内のダブルメニュー)を条件付きでレンダリングします。Bean Validationを使用して検証されるフォームには、他にもいくつかのフィールドがあります。

問題:

commandButtonをクリックした後に検証エラーが発生し、エラーメッセージが表示された場合、ダブルメニューは再表示されません。bean.type =='double'は正しくないようです。しかし、なぜ?selectOneMenu自体は、選択された項目としてオプションdoubleを表示します。

@javax.inject.Named
@javax.enterprise.context.RequestScoped
public class Bean {

private enum MyEnum {
    Single, Double
}

private MyEnum type;

public MyEnum getType() {
    return type;
}

public void setType(MyEnum type) {
    this.type = type;
}

public MyEnum [] getTypes() {
    return MyEnum.values();
}


<h:form>
<h:selectOneMenu value="#{bean.type}">
  <f:selectItems value="#{bean.types}" />
  <f:ajax render="doublemenu" />
</h:selectOneMenu>

<h:panelGroup id="doublemenu">
  <h:panelGroup rendered="#{bean.type == 'double'}">
    <h:selectOneMenu ...>
    </h:selectOneMenu>
  </h:panelGroup>
</h:panelGroup>
<h:inputText id="VALIDATED"/>
<h:commandButtonaction="#{bean.save}"
</h:form>

ところで:bean.saveは実行されません

4

1 に答える 1

4

これは、Beanがリクエストスコープであるためです。リクエストスコープのBeanは、すべてのリクエストの終了時にガベージされ、すべてのリクエストの開始時に新しく作成されます。これは、同じビューの個々のajaxリクエストにも当てはまります。

rendered属性は、送信された値の収集中にも評価されます(要求値の適用フェーズ)。ただし、送信された値が収集される時点では、#{bean.type}明らかにまだ設定されていません(モデル値の更新フェーズで収集された送信値に基づいて設定する必要があります)。Beanはリクエストスコープであるため、前のリクエストから送信された値ではなく、デフォルト値を返します。

これを修正するには、基本的に2つの方法があります。

  1. Beanをもう少し広い範囲に入れます。JSFは@ViewScopedまさにこの目的のためにを提供します。これは現在のJSF2.1バージョンにあり、CDIとのみ互換性がありません。JSFに切り替えること@ManagedBeanができない場合は、MyFaces CODIを使用してJSFをCDIに透過的にブリッジする@ViewScopedか、JSF2.2がCDI互換性@ViewScopedをすぐに利用できるようになるのを待つ必要があります。

  2. Beanプロパティの代わりにリクエストパラメータを確認してください。

    <h:selectOneMenu binding="#{type}" ...>
        ...
    </h:selectOneMenu>
    
    <h:panelGroup rendered="#{param[type.clientId] == 'Double'}">
    

これはすべて列挙型とはまったく関係がないことに注意してください。たとえば、を使用した場合もまったく同じ問題が発生しStringます。また、コード例のタイプミスを修正したことにも注意してください。列挙値のDoubleは、とはまったく同じではありませんdouble

参照:

于 2013-02-12T18:07:55.817 に答える