2010-10-27 22 views
0

Je dispose d'un bloc conceptuel sur l'utilisation d'un composant composite JSF 2.0 dans une page parente. Je comprends comment implémenter un ActionListener (et d'autres) pour l'action d'un composant composite mais comment est-ce connecté pour que la page parentale soit consommée? Par exemple, je souhaite que mon composant composite de connexion effectue une authentification et, lorsqu'il est terminé, informe le bean backing de la page parent via l'événement (ActionListener?) Pour effectuer un travail d'initialisation de l'interface utilisateur. La clé ici est le composant de connexion dirait, "Hey, j'ai terminé et l'utilisateur est bon.Evénement Evénement Composant Composant JSF 2.0 dans le bean de support de la page parente

Merci d'avance pour l'aide.

Paix.

Chris

Répondre

0

Une façon je trouve que vous pouvez acomplish utilise ce composant composite + type de composant personnalisé + ActionSource2 + événements système.

Dans l'interface de votre composite définir un type de composant (lorsqu'ils ne sont pas definied, la mise en œuvre (Mojarra ou MyFaces) utilise un type de composant par défaut.

<cc:interface componentType="example.Login"> 
    <cc:attribute name="text" type="java.lang.String"/> 
    <cc:attribute name="actionExpression" method-signature="void method()"/> 
</cc:interface> 

<cc:implementation> 
    <p> 
     <h:outputLabel value="User"/> 
     <h:inputText id="user"/> 
    </p> 
    <p> 
     <h:outputLabel value="Password"/> 
     <h:inputSecret id="password"/> 
    </p> 
</cc:implementation> 

Ce type de composant est une classe java qui implémente NamingContainer (UINamingContainer est une sous-classe du composant implémentant cette interface.) Ensuite, vous devez implémenter ActionSource2 pour pouvoir générer un événement d'action lorsque l'utilisateur est vérifié

Le verifyng doit être après que les composants utilisateur et mot de passe ont été validés. votre vérification, mais JSF PROCESS VALIDATIONS). Pour savoir quand la validation a eu lieu, nous utilisons System Events.

Ceci est un exemple de code pour le composant personnalisé. La classe implémente les méthodes de l'interface ActionSource2 et remplace la diffusion pour gérer ActionEvent. J'utilise certaines classes spécifiques dans Mojarra (parce que l'héritage entre ActionSource et ActionSource2).

@FacesComponent("example.Login") //Component type in the composite 
@ListenerFor(systemEventClass=PostValidateEvent.class) //Event to listen for user and password verification 
public class LoginComponent extends UINamingContainer implements ActionSource2{ 

    @Override 
    public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { 
     if(event instanceof PostValidateEvent){ 
      System.out.println("post validate"); 
     } 
     super.processEvent(event); 
     String user=(String) ((HtmlInputText)findComponent("user")).getValue(); 
     String password=(String) ((HtmlInputSecret)findComponent("password")).getValue(); 
     System.out.println("user: "+user); 
     System.out.println("password: "+password); 
     //a simple logic for verification 
     if(user != null && user.equals("victor") && password != null && password.equals(user)){ 
      System.out.println("user ok"); 
      queueEvent(new ActionEvent(this)); 
     } 
    } 


    private MethodExpression exp; 

    @Override 
    public MethodExpression getActionExpression() { 
     return exp; 
    } 

    @Override 
    public void setActionExpression(MethodExpression action) { 
     exp=action; 
    } 

    @Override 
    public MethodBinding getAction() { 
     return exp != null ? new MethodBindingMethodExpressionAdapter(exp): null; 
    } 

    @Override 
    public void setAction(MethodBinding action) { 
     setActionExpression(new MethodExpressionMethodBindingAdapter(action)); 
    } 

    private MethodBinding actionListener; 

    @Override 
    public MethodBinding getActionListener() { 
     return actionListener; 
    } 

    @Override 
    public void setActionListener(MethodBinding actionListener) { 
     this.actionListener=actionListener; 
    } 

    private boolean i; 

    @Override 
    public boolean isImmediate() { 
     return i; 
    } 

    @Override 
    public void setImmediate(boolean immediate) { 
     this.i=immediate; 
    } 

    List<ActionListener> listeners=new LinkedList<ActionListener>(); 

    @Override 
    public void addActionListener(ActionListener listener) { 
     listeners.add(listener); 
    } 

    @Override 
    public ActionListener[] getActionListeners() { 
     return listeners.toArray(new ActionListener[0]); 
    } 

    @Override 
    public void removeActionListener(ActionListener listener) { 
     listeners.remove(listener); 
    } 

    @Override 
    public void broadcast(FacesEvent event) throws AbortProcessingException { 
     super.broadcast(event); 

     if (event instanceof ActionEvent) { 
      FacesContext context = getFacesContext(); 
      MethodBinding binding = getActionListener(); 
      if (binding != null) { 
       binding.invoke(context, new Object[] { event }); 
      } 

      ActionListener listener = context.getApplication().getActionListener(); 
      if (listener != null) { 
       listener.processAction((ActionEvent) event); 
      } 
     } 
    } 

} 

Et voici le code dans la page en utilisant:

<ez:login actionExpression="#{bean.logged}"/> 
+0

Merci Victor pour le segment de code. Je reviendrai à mes composants composites dans une semaine et j'examinerai plus en détail votre implémentation. C'est vraiment bien. Merci encore! – Chris