1

JSF 2 (Glassfish 3.1.1 の mojarra) を使用して作成されたいくつかのテスト中に、説明できない奇妙な動作に直面しました。

これは私のマネージドBeanです:

@ManagedBean
@RequestScoped
public class TestBean {
    private int id;

    public void hideButton() {
        id = 0;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

ここに私のxhtmlページがあります

   <h:form>
       <h:inputHidden value="#{testBean.id}"/>

       <h:outputText value="#{testBean.id}"/>

       <h:commandButton value="set 1"
                    actionListener="#{testBean.setId(1)}">
       </h:commandButton>

       <h:commandButton value="hide button"
                    action="#{testBean.hideButton}" rendered="#{testBean.id > 0}">
       </h:commandButton>            
   </h:form>

ページの初期ロード時に「ボタンを隠す」ボタンが表示されないことを期待していましたが、これは実際の事実です。ボタン「set 1」をクリックすると、ボタン「hide button」が表示されますが、これも当然のことです。本当に理解できないのは、「ボタンを隠す」ボタンを次にクリックしても、メソッドtestBean.hideButtonが呼び出されず、idが0に設定されないという事実です。BalusCからの非常に役立つ回答を読みました(本当にありがとう)ここ

commandButton/commandLink/ajax アクション/listener メソッドが呼び出されていないか、入力値が更新されていません

問題は「レンダリング」属性に関連していることを認識し、それを削除すると、アクションが呼び出されます。しかし、私の知る限り、クラス メンバーは UPDATE MODEL VALUES フェーズで初期化する必要があり、レンダリングされた属性に記載されている条件は INVOKE APPLICATION フェーズで true と評価され、アクションを呼び出す必要があります。

この例は、Bean のスコープを View/Session に変更すると機能します。ただし、「非表示ボタン」からrender属性を削除しても問題なく動作します

誰かがそのような行動を説明してくれますか?

つまり、レンダリングされた属性の式が評価されて、アクションを呼び出さない決定を下すのはどの段階でしょうか?

4

2 に答える 2

4

このrendered属性は、JSF がどのアクションを呼び出す必要があるかを特定する必要があるときに、リクエスト値の適用フェーズでも評価されます。と評価されfalseた場合、アクションは識別できないため、呼び出されません。

この問題は、マネージド Bean の範囲が狭すぎるために発生します。マネージド Bean はリクエスト スコープであるため、レスポンスの最後に破棄され、後続のリクエストで (すべてのプロパティがデフォルトに設定されて) 再作成されます。属性が依存するモデル値renderedは、モデル値の更新フェーズ中にのみ更新されますが、これでは遅すぎます。代わりにマネージド Bean をビュー スコープに配置する必要があります。

Bean スコープをビュー スコープに変更する以外に、rendered属性の代わりにリクエスト パラメータ マップの値を確認する方法もあります。

<h:form id="form">
    <h:inputHidden id="id" ... />

    <h:commandButton ... rendered="#{param['form:id'] gt 0}" />
</h:form>

(ちなみに、>代わりに をgt使用しているのは、Facelets の代わりに非推奨の JSP ビュー テクノロジを使用していることを示しています。Facelets に移行することを強くお勧めします)

以下も参照してください。

于 2012-07-06T12:51:43.587 に答える
0

私は自分自身が問題の原因を見つけました。

UIComponentBase.processDecodes メソッドは (Apply Request Values フェーズで) isRendered を呼び出します。これは false を返します。これは、Update Model Values の前であるためです。コンポーネントのデコードをスキップします。

可能な回避策がいくつかありますが、それらはすべてクールではありませんが、それでも機能します

マネージド Bean の (ポスト) コンストラクターで、リクエストパラメーターから必要な値を手動で設定することができます。または使用する

于 2012-07-06T12:43:18.693 に答える