Glassfish3.1.1 による Mojarra-2.1.3 (Netbeans7.1 で配布)
リスナー void reset() を持つ @SessionScoped バッキング Bean トラッカーがあります。
以下は、クエリ パラメーター ID を受け取る /block/view.xhtml などの template.xhtml を使用するすべての XHTML ページの f:metadata で正常に機能します。
<f:view>
<f:metadata>
<f:viewParam name="id" value="#{blockManager.id}"/>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
</f:metadata>
</f:view>
<ui:composition template="/template.xhtml">
予想どおり、ページをロード (GET) またはリロードするたびに、id クエリ パラメータに関係なく、 #{tracker.reset} リスナーが呼び出されます (デバッグ ログで明らかになります)。
ただし、その f:event をすべての XHTML ページ (何百もある) に含める必要があるのは面倒なので、代わりに template.xhtml の f:metadata に含めることを最初に試みました。しかし、私がしたとき、何か奇妙なことが起こりました。#{tracker.reset} を 1 回だけ呼び出し、最初に /block/view.xhtml がロードされたとき (id クエリ パラメータが何であれ)、その後、別のビュー ID を持つ別のページをロードするまで再度呼び出されませんでした。 /actor/view.xhtml、/block/list.xhtml、/index.html など。
template.xhtml で #{facesContext.viewRoot.viewId} を使用して viewId を調べました。viewId の観点からは、クエリ パラメータ id が、異なる id クエリ パラメータで呼び出された異なる block/view.xhtml?id=[id] ページを区別する役割を果たさないことは明らかです。viewId は常に '/block /view.xhtml'.
このstackoverflowへの投稿の執筆中に、私は自分の問題の解決策を発見しました.f:eventをtemplate.xhtmlのf:metadataの外側に配置するだけです(f:eventsのグループ化のためにtemplate.xhtmlのf:metadataを使用していました) )。これは template.xhtml で機能します。
<f:metadata>
..
</f:metadata>
<f:event type="preRenderView" listener="#{tracker.reset}"/>
<h:head>
しかし、私はまだ次の質問があります。
Q: テンプレートの f:metadata 内に f:event を配置するかどうかで違いが生じるのはなぜですか?
私が尋ねる理由は、ここ Stackoverflow には、template.xhtml での f:metadata の使用と、テンプレートの f:metadata 内での f:event の使用の両方の例がたくさんあるからです。
BalusC は、いつ f:viewAction / preRenderView と PostConstruct を使用するのですか? :
preRenderView イベントは、すべての HTTP 要求で呼び出されます。
これは、最終的な XHTML ページの f:metadata 内、またはテンプレートの f:metadata の外に preRenderView f:event があるが、テンプレート。
テンプレートの f:metadata に f:event を含めるか、テンプレートで f:metadata を使用するかについては、いくつかの議論があるようです。
JSF2 完全リファレンス (Burns and Schalk) p.540 は次のように述べています。
f:metadata タグは、Facelets ビューのメタデータを指定するために使用される要素のセットをカプセル化するため、f:view タグの子である必要があり、テンプレートに表示されない場合があります。JSF2.0 では、このタグの唯一の目的は f:viewParam タグをカプセル化することです。
しかし、Stackoverflow には、f:metadata がテンプレート内で使用されている例がたくさんあり、f:metadata 内で f:event が使用されている例がたくさんあります。ここでも議論されています:
f:metadata 内に f:event を配置するかどうかは重要ですか?
BalusC が有益に説明した場所:
.. <f:event> は、厳密には <f:metadata> 内に配置する必要はありません。任意のコンポーネントに取り付けることができます。..確かに、 <f:viewParam> の束があり、 <f:event> をフックしてすべてのビューパラメーターの後にアクションを呼び出したい場合はいつでも、 <f:metadata> 内に配置される純粋な自己記録目的のためです。設定されています。..
しかし、上記の私の経験は、テンプレートの f:metadata 内に f:event を配置すると、わずかに異なる (奇妙な) 動作が発生することを示しています。なんで ?