JSF 1.2 NavigationHandler пользовательская навигация - PullRequest
0 голосов
/ 05 марта 2010

Я пытаюсь расширить NavigationHandler в JSF 1.2 и сохранить стек посещенных страниц (точнее, view-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 - это простой класс с 3 строками для actionName, actionMethod и ViewId.

Мои правила навигации, вface-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>

У меня есть только 3 страницы, index.jsp, page_a1.jsp и page_a2.jsp.

Вы можете видеть в навигационных кейсах связи между ними. То, что я хочу, - это возможность "go_back" из page_a2.jsp, либо в page_a1.jsp, либо в index.jsp.

Нормальная навигация работает нормально: Индекс -> 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
сверху

Когда я пытаюсь "go_back" из P2, я ожидаю, что он вернется на страницу 1. Это не так (страница просто перезагружается). Если я попробую второй раз, это сработает.

Я думаю, это потому, что с первой попытки я вырываюсь из стека, и он пытается выполнить действие "to_page_a2" - не удается. Во второй раз он снова выскакивает из стека, но теперь он пытается с «i_to_1», и это .. каким-то образом работает.

Может кто-нибудь помочь мне с этим? Я надеюсь, что мои объяснения были достаточно ясны - если нет, пожалуйста, спросите.

Любая подобная идея также приветствуется. Я должен отметить, что 2 дня назад я начал использовать JSF, и мне не очень понятно, что там происходит.

Спасибо, Alex

Ответы [ 2 ]

1 голос
/ 05 марта 2010

Хорошо, я нашел решение (или, точнее, патч, потому что я не уверен, что оно работает слишком хорошо).

Я высовываю 2 элемента вместо одного, прежде чем сделать"go_back".

Пример: индекс -> P1 -> P2 - go_back;Я должен идти к P1 (P2 -> P1)

Чтобы достичь P1, мне нужно перейти к точке «Индекс», а затем попытаться перейти к P1.(Мне нужно сделать один шаг перед страницей, на которую я хочу вернуться):

Стек:1: pop P1 (я хочу добраться до него, поэтому не могу его использовать; я просто удаляю его из стека)2: pop Index - используйте индексную точку, чтобы перейти к 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);
    }
}

Надеюсь, это кому-нибудь поможет!

Кроме того, я уверен, что это может работать не очень хорошо, я еще не слишком много тестировал.

Любые другие идеи приветствуются.

СпасибоAlex

0 голосов
/ 18 декабря 2015

Я реализовал нечто подобное;Я также перехватил клавишу «backspace» в javascript, чтобы щелкнуть скрытую команду linkLink, которая запускает переход к предыдущему представлению в стеке (или к любой комбинации / логике, которая вам нужна).

В моем использованииcase Я упростил логику навигационных кейсов, чтобы легче перемещаться из точки в точку в коде:

public static void navigate(String action, String outcome) {
    FacesContext fc = FacesContext.getCurrentInstance();
    NavigationHandler nh = fc.getApplication().getNavigationHandler();
    nh.handleNavigation(fc, action, outcome);
}
...