2010-03-05 4 views
0

Я пытаюсь расширить NavigationHandler в JSF 1.2 и сохранить стек посещенных страниц (точнее, view-ids вместе с действием и выходом).JSF 1.2 Навигационная навигация NavigationHandler

Я пытаюсь реализовать пользовательское действие, такое как «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.

Мои правила навигации, в лицах-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; без проблем.

Если я: 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

ответ

1

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

Я вывожу 2 предмета, вместо одного, прежде чем я сделаю «go_back».

Ex: Index -> P1 -> P2 - go_back; Я должен перейти к P1 (P2 -> P1)

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

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

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

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

public static void navigate(String action, String outcome) { 
    FacesContext fc = FacesContext.getCurrentInstance(); 
    NavigationHandler nh = fc.getApplication().getNavigationHandler(); 
    nh.handleNavigation(fc, action, outcome); 
} 
Смежные вопросы