2010-03-05 35 views
0

我想扩展JSF 1.2中的NavigationHandler,并保留访问页面(更确切地说,视图ID,以及操作和输出)的堆栈。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。

我的导航规则,在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> 

我只有3页,index.jsp中,page_a1.jsp和page_a2.jsp。

您可以在导航案例中看到它们之间的连接。我想要的是能够从page_a2.jsp“go_back”到page_a1.jsp或index.jsp。

正常的导航工作正常:索引 - > P1 - > P2 - > P1 - > P2 - >索引;没问题。

如果我:索引 - > 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”操作 - 失败。 第二次,它从堆栈中再次弹出,但现在它尝试使用“i_to_1”,而这.. ..不知何故,工作。

任何人都可以帮助我吗?我希望我的解释清楚 - 如果没有,请问。

任何类似的想法也是受欢迎的。我应该提及的是,在2天前我开始使用JSF,并且我不清楚在那里发生的所有事情。

谢谢 亚历

回答

1

好吧,我已经找到了解决方案(或更好说,补丁,因为我不知道它的工作原理太清楚)。

在我执行“go_back”之前,我弹出2个项目,而不是一个项目。

例如:Index - > P1 - > P2 - go_back;我应该去P1(P2 - > P1)

为了能够达到P1,我实际上必须去“索引”点,然后尝试去P1。(我有一个一步之前的页面我想回去):

堆栈:
1:流行P1(我想要得到它,所以我不能用它;我刚刚从堆栈中删除它)
2:弹出索引 - 使用索引点去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); 
    } 
} 

我希望这有助于有人!

此外,我相信这可能不会很好,我还没有测试太多。

欢迎任何其他想法。

感谢
亚历克斯

0

我实现了类似的东西; 我也拦截了javascript中的“退格键”,以便点击一个隐藏的命令链接来触发导航到堆栈中的前一个视图(或者您需要的任何组合/逻辑)。

以我使用情况下,我扁平的导航例的逻辑,以从点更容易地导航到代码内指向:

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