2 つのビュー (a.xhtml
とb.xhtml
) があり、そのうちの 1 つは他のビューへのリンクを含んでいます。最初のビュー:
- 現在のビュー マップに値を設定して使用します。
- リンクのクエリ文字列にビュー パラメータを自動的に含めるために
b.xhtml
withh:link
using を指します。includeViewParams="true"
a.xhtml
:
<f:view >
<f:metadata>
<f:viewAction>
<!-- just set any value to force view map creation... -->
<f:setPropertyActionListener target="#{viewScope.username}" value="John" />
</f:viewAction>
</f:metadata>
<h:link id="alink" value="Go to B" outcome="b" includeViewParams="true" />
<h:form>
<h:commandButton id="away" action="b" value="Navigate away" immediate="false" />
</h:form>
</f:view>
</html>
とb.xhtml
:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<f:view >
<f:metadata>
<f:viewParam id="id" name="userid" value="1" />
</f:metadata>
</f:view>
</html>
また、ViewMapListener
一度アクセスすると発生する「偽の」ビュー マップ破壊イベント呼び出しを示すために、ここで を作成していa.xhtml
ます。私のfaces-config.xml
中で私はこのエントリを持っています:
<system-event-listener>
<system-event-listener-class>org.my.TestViewMapListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreDestroyViewMapEvent</system-event-class>
<source-class>javax.faces.component.UIViewRoot</source-class>
</system-event-listener>
どこTestViewMapListener
がこのようなものです:
public class TestViewMapListener implements ViewMapListener {
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException {
if (event instanceof PreDestroyViewMapEvent) {
PreDestroyViewMapEvent viewMapEvent = (PreDestroyViewMapEvent)event;
UIViewRoot viewRoot = (UIViewRoot)viewMapEvent.getComponent();
System.out.println("PreDestroyViewMapEvent: "+viewRoot.getViewId());
}
}
...
ページa.xhtml
がレンダリングされると、リスナーは次の行を出力します。
PreDestroyViewMapEvent: /b.xhtml
b.xhtml
一度も訪れたことがないので奇妙です。ボタンで移動すると"Navigate away"
、正しいイベントが期待どおりに出力されます。
PreDestroyViewMapEvent: /a.xhtml
includeViewParams="true"
リンクで使用している場合にのみ、誤ったイベントが発生します。デバッグすることで、com.sun.faces.application.view.ViewMetadataImpl.createMetadataView(FacesContext)
一時的にFacesContext
UIViewRoot に設定されているために発生することがわかりますb.xhtml
元のビュー マップの浅いコピーが作成され、一時的なビュー ルートに設定されます。これはおそらく、リンクのクエリ文字列パラメーターの値を正しく検出するために行われます。また、操作中はイベントを一時的にオフにしますが、オンに戻すのが早すぎます (「finally」ブロックを参照)。そのため、ビュー マップの一時的なコピーに対してビュー マップの破棄イベントが「誤って」発生しますが、イベントは発生しません。現時点では、元のビュー マップ自体が期待されています。元のマップが破壊されたのか、それとも「ゴースト」の偽のイベントなのかを検出するために、いくつかの追加のアクションを実行する必要があるため、頭痛の種です。
これはバグですか、それとも望ましい動作ですか? Mojarra 2.2.12 を使用しています。