1

2 つのビュー (a.xhtmlb.xhtml) があり、そのうちの 1 つは他のビューへのリンクを含んでいます。最初のビュー:

  • 現在のビュー マップに値を設定して使用します。
  • リンクのクエリ文字列にビュー パラメータを自動的に含めるためにb.xhtmlwith h:linkusing を指します。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)一時的にFacesContextUIViewRoot に設定されているために発生することがわかりますb.xhtml元のビュー マップの浅いコピーが作成され、一時的なビュー ルートに設定されます。これはおそらく、リンクのクエリ文字列パラメーターの値を正しく検出するために行われます。また、操作中はイベントを一時的にオフにしますが、オンに戻すのが早すぎます (「finally」ブロックを参照)。そのため、ビュー マップの一時的なコピーに対してビュー マップの破棄イベントが「誤って」発生しますが、イベントは発生しません。現時点では、元のビュー マップ自体が期待されています。元のマップが破壊されたのか、それとも「ゴースト」の偽のイベントなのかを検出するために、いくつかの追加のアクションを実行する必要があるため、頭痛の種です。

これはバグですか、それとも望ましい動作ですか? Mojarra 2.2.12 を使用しています。

4

0 に答える 0