5

OmniFaces Showcase アプリからこのテンプレートのコードをチェックアウトしていたときに、次の条件が で使用されていることに遭遇しました。p:selectOneMenu

disabled="#{facesContext.postback and not facesContext.renderResponse}"

アプリを使用すると、selectOneMenuが無効になることはないように見えますが、このコードは実際には何をしているのでしょうか?

ページが JSF コンポーネント ( commandButton/commandLinkなど)によって生成された POST 要求の結果であることfacesContext.postbackはわかっていますが、ビューで評価されたときに通常予想される状態は何でしょうか?truefacesContext.renderResponse

更新:おっと、今コメントを見ました:それらは、フォームがなくてもモデル値を設定できないと文句を言うため、レンダリング応答以外のフェーズでは無効になっています

facesContext.renderResponseしたがって、Faces のライフサイクル中に条件が数回評価されtrue、最後の状態 (renderResponse) に到達するまでコンポーネントが無効になっていると推測していますfalse。それは正しいですか?

4

2 に答える 2

5

これらの<p:selectOneMenu>コンポーネントは、最小限のコードで適切なドロップダウン メニューを作成するために実際に悪用されてい<div><ul><li>ます ;) それらの値は、設計上読み取り専用である現在のメニュー グループとページを表します (設定メソッドはありません)。window.locationナビゲーションは、変更イベント中に処理される JavaScript によって行われます。それらはフォームの一部ではなく、フォームの送信には関与しません。

このdisabled属性は理論的には必須ではありませんが、まったく同じページ内の別の場所にある ajax 以外の JSF フォームが同期的に送信された場合、PrimeFacesはフォームにまったく含まれていなくても、全体としてそれをSelectOneMenuRenderer試みます。decode()その値のセッターがないため、モデル値が更新されると、最終的に次の例外が発生します。

javax.el.PropertyNotWritableException: /WEB-INF/templates/showcase.xhtml @28,80 value="#{parent.children[0].viewId}": The class 'org.omnifaces.showcase.Page' does not have a writable property 'viewId'.
    at com.sun.faces.facelets.el.TagValueExpression.setValue(TagValueExpression.java:136)
    at javax.faces.component.UIInput.updateModel(UIInput.java:818)
    at javax.faces.component.UIInput.processUpdates(UIInput.java:735)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at org.primefaces.component.panel.Panel.processUpdates(Panel.java:304)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIComponentBase.processUpdates(UIComponentBase.java:1242)
    at javax.faces.component.UIViewRoot.processUpdates(UIViewRoot.java:1231)
    at com.sun.faces.lifecycle.UpdateModelValuesPhase.execute(UpdateModelValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)

postback中にdisabled属性が評価されると、リクエスト値の適用フェーズがスキップされるため、モデル値の更新もスキップされます。ただし、レンダリング レスポンス フェーズでも評価されると、選択できなくなります (したがって、使用できなくなります)。そのため、レンダリング レスポンス フェーズでは true と評価されるべきではありません。表現trueSelectOneMenuRendererdecode()true

disabled="#{facesContext.postback and not facesContext.renderResponse}"

まさにそれを実現します。全体として、これは基本的に の奇妙な動作に対する一種の回避策ですSelectOneMenuRenderer(根本的な原因はまだ調査していません)。

自分でテストするには、プロジェクトをプルし、属性を削除して、ショーケース ページdisabledなどで同期送信を呼び出します。<o:onloadScript>

于 2012-12-28T12:30:39.167 に答える
0

これは、renderResponse()が呼び出されたかどうかを読み取るためのgetter 状態に評価されます。このメソッドは、JSF ライフサイクルに後続のフェーズをスキップして、応答の発行に直接進むように指示するために使用されます (たとえば、検証の失敗の場合)。

于 2012-12-28T11:53:27.930 に答える