【问题标题】:JSF 1.2 NavigationHandler custom navigationJSF 1.2 NavigationHandler 自定义导航
【发布时间】:2010-03-05 14:02:03
【问题描述】:

我正在尝试扩展 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 只是一个简单的类,包含 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 的,我不太清楚那里发生的一切。

谢谢你, 亚历克斯

【问题讨论】:

    标签: jsf navigation navigationcontroller faces-config


    【解决方案1】:

    好的,我找到了一个解决方案(或者,更好的说法是一个补丁,因为我不确定它是否工作得很好)。

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

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

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

    堆栈:
    1:pop P1(我想拿到它,所以我不能使用它;我只是将它从堆栈中删除)
    2:pop Index - 使用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);
        }
    }
    

    我希望这对某人有帮助!

    另外,我确信这可能不是很好,我还没有测试太多。

    欢迎任何其他想法。

    谢谢
    亚历克斯

    【讨论】:

      【解决方案2】:

      我已经实现了类似的东西; 我还截获了 javascript 中的“退格”键,以便单击隐藏的 commandLink,该命令链接触发导航到堆栈中的上一个视图(或您需要的任何组合/逻辑)。

      在我的用例中,我已经扁平化了导航用例的逻辑,以便在代码中更轻松地从一个点导航到另一个点:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-03-17
        • 1970-01-01
        • 2012-03-15
        • 1970-01-01
        • 2023-04-05
        • 1970-01-01
        • 2012-04-26
        • 1970-01-01
        相关资源
        最近更新 更多