2010-03-05 3 views
0

J'essaie d'étendre le NavigationHandler dans JSF 1.2, et de conserver une pile des pages visitées (plus précisément, les id-view, avec l'action et la sortie).Navigation personnalisée JSF 1.2 NavigationHandler

J'essaie d'implémenter une action personnalisée, telle que "go_back", qui me ramènera à la page précédente.

Mon NavigationHandler actuelle:

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); 
    } 
} 

Le est juste une point de navigation simple classe avec 3 cordes, pour le actionName, actionMethod et viewId.

Mes règles de navigation, en 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> 

Je n'ont 3 pages, index.jsp, page_a1.jsp et page_a2.jsp.

Vous pouvez voir dans les cas de navigation, les connexions entre eux. Ce que je veux, c'est pouvoir "go_back" depuis page_a2.jsp, vers page_a1.jsp, ou vers index.jsp.

La navigation normale fonctionne correctement: Index -> P1 -> P2 -> P1 -> P2 -> Index; aucun problème.

Si je fais: Index -> P1 -> P2

je vais avoir sur la pile:
fond
1: index.jsp/i_to_1 -> page_a1.jsp
2: page_a1 .jsp/to_page_a2 -> page_a2.jsp
top

Lorsque je tente "GO_BACK" de P2, je pense à revenir à la page 1. il n'a pas (la page est juste reloaded). Si je l'essaye une deuxième fois, cela fonctionne.

Je pense que c'est parce qu'au premier essai, je saute de la pile, et il essaie avec l'action "to_page_a2" - échoue. La seconde fois, il ressort de la pile, mais maintenant il essaie avec "i_to_1", et cela fonctionne d'une façon ou d'une autre.

Quelqu'un peut-il m'aider avec ceci? J'espère que mes explications étaient assez claires - sinon, demandez s'il vous plaît.

Toute idée similaire est également la bienvenue. Je dois mentionner que c'était il y a deux jours que j'ai commencé à utiliser JSF, et ce n'est pas très clair pour moi tout ce qui s'y passe.

Merci, Alex

Répondre

1

Ok, je l'ai trouvé une solution (ou, pour mieux dire, un patch, parce que je ne suis pas sûr qu'il fonctionne trop bien).

Je saute 2 articles, au lieu d'un, avant de faire le "go_back".

Ex: Index -> P1 -> P2 - go_back; Je suis supposé aller à P1 (P2 -> P1)

Pour pouvoir atteindre P1, je dois effectivement aller au point "Index", puis essayer d'aller à P1.(Je dois aller avec une étape avant la page Je veux revenir à):

La pile:
1: P1 pop (je veux aller, donc je ne peux pas l'utiliser; Je viens de le retirer de la pile)
2: pop Index - utiliser le point d'index pour aller à P1 (même si je suis réellement P2)

le code mis à jour:

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); 
    } 
} 

J'espère que cette aide Quelqu'un!

Aussi, je suis sûr que cela peut ne pas fonctionner très bien, je n'ai pas testé trop encore.

Toutes les autres idées sont les bienvenues.

Merci
Alex

0

J'ai mis quelque chose de semblable; J'ai aussi interceptés sur la touche « backspace » javascript afin de cliquer sur un commandLink caché qui déclenche la navigation à la vue précédente dans la pile (ou toute combinaison/logique que vous avez besoin).

Dans mon cas d'utilisation que j'ai aplatis la logique des cas de navigation afin de naviguer plus facilement d'un point à l'intérieur du code:

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