0

私は、JSF 1.2 で NavigationHandler を拡張し、アクセスしたページのスタック (より正確には、ビュー ID、アクションおよび出力) を保持しようとしています。

前のページに戻る「go_back」などのカスタム アクションを実装しようとしています。

私の現在のNavigationHandler:

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import java.util.Stack;

public class NavigationManager extends NavigationHandler {

    NavigationHandler _base;
    private Stack trailPointStack;

    public NavigationManager(NavigationHandler base) {
        super();
        _base = base;
        trailPointStack = new Stack();
    }

    @Override
    public void handleNavigation(FacesContext fc, String actionMethod, String actionName) {
        NavigationPoint point;
        String currentAction = actionName;
        String currentMethod = actionMethod;

        if (actionName.equals("go_back") && (trailPointStack.size() > 0)) {
            point = (NavigationPoint) trailPointStack.pop();//better check if there is something in there
            //currentAction = null;
            //currentMethod = null;
            currentAction = point.getAction();
            currentMethod = point.getActionMethod();
            fc.getViewRoot().setViewId(point.getViewId());
        } else {
            point = new NavigationPoint(actionName, actionMethod, fc.getViewRoot().getViewId());
            trailPointStack.push(point);
        }

        //check stack size to be less than 6 items
        while (trailPointStack.size() > 5) {
            trailPointStack.removeElementAt(0);
        }

        _base.handleNavigation(fc, currentMethod, currentAction);
    }
}

NavigationPoint は、actionName、actionMethod、ViewId の 3 つの文字列を持つ単純なクラスです。

faces-config.xml の私のナビゲーション ルール:

<navigation-rule>
 <description>Index to subpages</description>
 <from-view-id>/index.jsp</from-view-id>
     <navigation-case>
        <from-outcome>i_to_1</from-outcome>
        <to-view-id>/page_a1.jsp</to-view-id>
        <redirect />
     </navigation-case>
     <navigation-case>
        <from-outcome>to_page_a2</from-outcome>
        <to-view-id>/page_a2.jsp</to-view-id>
        <redirect />
     </navigation-case>
 </navigation-rule>

 <navigation-rule>
 <description>From page a1</description>
 <from-view-id>/page_a1.jsp</from-view-id>
     <navigation-case>
        <from-outcome>to_page_a2</from-outcome>
        <to-view-id>/page_a2.jsp</to-view-id>
        <redirect />
     </navigation-case>
 </navigation-rule>

 <navigation-rule>
 <description>From page a2</description>
 <from-view-id>/page_a2.jsp</from-view-id>
     <navigation-case>
        <from-outcome>to_page_a1</from-outcome>
        <to-view-id>/page_a1.jsp</to-view-id>
        <redirect />
     </navigation-case>

     <navigation-case>
        <from-outcome>to_index</from-outcome>
        <to-view-id>/index.jsp</to-view-id>
        <redirect />
     </navigation-case>
 </navigation-rule>

index.jsp、page_a1.jsp、page_a2.jsp の 3 つのページしかありません。

ナビゲーションケースで、それらの間の接続を見ることができます。私が望むのは、page_a2.jsp から page_a1.jsp、または index.jsp に「戻る」ことができるようにすることです。

通常のナビゲーションは正常に機能します: Index -> P1 -> P2 -> P1 -> P2 -> Index; 問題なし。

もしそうなら: インデックス -> P1 -> P2

私はスタックに持っています:
下部
1:index.jsp/i_to_1 -> page_a1.jsp
2:page_a1.jsp/to_page_a2 -> page_a2.jsp
上部

P2 から「go_back」を試みると、ページ 1 に戻ると思いますが、そうではありません (ページがリロードされるだけです)。もう一度試してみると、うまくいきます。

最初の試行でスタックからポップし、アクション「to_page_a2」で試行して失敗したためだと思います。2 回目は、スタックから再びポップしますが、今度は "i_to_1" で試行し、これは.. 何とか動作します。

誰でもこれで私を助けることができますか?私の説明が十分に明確であったことを願っています。そうでない場合は、お尋ねください。

同様のアイデアも大歓迎です。私が JSF を使い始めたのは 2 日前のことです。

ありがとう、アレックス

4

2 に答える 2

1

わかりました、解決策を見つけました (または、うまく機能するかどうかわからないため、パッチをより適切に言います)。

「go_back」を実行する前に、1 つではなく 2 つのアイテムをポップしています。

例: インデックス -> P1 -> P2 - go_back; P1に行くことになっています(P2 -> P1)

P1 に到達するには、実際に「インデックス」ポイントに移動してから、P1 に到達しようとする必要があります。(戻りたいページのに 1 ステップ進む必要があります):

スタック:
1: P1 をポップします (取得したいので使用できません。スタックから削除するだけです)
2: インデックスをポップ - インデックス ポイントを使用して P1 に移動します (実際に P1 にいる場合でも) P2)

更新されたコード:

import javax.faces.application.NavigationHandler;
import javax.faces.context.FacesContext;
import java.util.Stack;

public class NavigationManager extends NavigationHandler {

    NavigationHandler _base;
    private Stack trailPointStack;

    public NavigationManager(NavigationHandler base) {
        super();
        _base = base;
        trailPointStack = new Stack();
    }

    @Override
    public void handleNavigation(FacesContext fc, String actionMethod, String actionName) {
        NavigationPoint point;
        String currentAction = actionName;
        String currentMethod = actionMethod;

        if (actionName.equals("go_back") && (trailPointStack.size() > 0)) {//"go_back" is the action that triggers the back move

            if (trailPointStack.size() == 1) {
                //It is the first page we visit (the second page in stack)
                point = (NavigationPoint) trailPointStack.pop();
                currentAction = null;
                currentMethod = point.getActionMethod();
            } else {
                trailPointStack.pop();//we get rid of the prev, and we go from prev-prev to prev :D
                point = (NavigationPoint) trailPointStack.pop();//actually the second one in the stack
                currentAction = point.getAction();
                currentMethod = point.getActionMethod();
            }

            fc.getViewRoot().setViewId(point.getViewId());
        } else {
            point = new NavigationPoint(actionName, actionMethod, fc.getViewRoot().getViewId());
            trailPointStack.push(point);
        }

        //check stack size to be max 10 items
        while (trailPointStack.size() > 10) {
            trailPointStack.removeElementAt(0);
        }

        _base.handleNavigation(fc, currentMethod, currentAction);
    }
}

これが誰かに役立つことを願っています!

また、これはうまく機能しない可能性があると確信しています。まだあまりテストしていません。

他のアイデアは大歓迎です。

ありがとう
アレックス

于 2010-03-05T16:17:45.507 に答える
0

私は似たようなものを実装しました。また、スタック内の前のビュー (または必要な組み合わせ/ロジック) へのナビゲーションをトリガーする非表示の commandLink をクリックするために、javascript の「バックスペース」キーをインターセプトしました。

私のユース ケースでは、コード内のポイントからポイントへの移動をより簡単にするために、ナビゲーション ケースのロジックをフラット化しました。

public static void navigate(String action, String outcome) {
    FacesContext fc = FacesContext.getCurrentInstance();
    NavigationHandler nh = fc.getApplication().getNavigationHandler();
    nh.handleNavigation(fc, action, outcome);
}
于 2015-12-18T12:54:33.283 に答える