2013-05-04 10 views
6

voglio utilizzare più action listener per impostare lo stato di due chicchi di backing prima di ulteriori trasformazionimultipli actionlisteners in JSF

1 ° modo:

<p:commandButton process="@this" > 
    <f:attribute name="key" value="#{node.getIdTestGroup()}" /> 
    <f:actionListener binding="#{testController.nodeListener}" /> 
<f:actionListener binding="#{testDeviceGroupController.prepareCreate}" /> 
</p:commandButton> 

E dare un'eccezione:

ATTENZIONE : /testGroup/List.xhtml @ 26,88 binding = "# {testController.nodeListener()}": metodo nodeListener non trovato javax.el.ELException: /testGroup/List.xhtml @ 26,88 binding = "# { testController.nodeListen er()} ": Metodo nodeListener non trovato

2 ° modo:

<p:commandButton process="@this" > 
    <f:attribute name="key" value="#{node.getIdTestGroup()}" /> 
    <f:actionListener binding="#{testController.nodeListener(event)}" /> 
    <f:actionListener binding="#{testDeviceGroupController.prepareCreate(event)}" /> 
</p:commandButton> 

evento è nullo sulle nodeListener e prepareCreate metodi

come farlo correttamente?

+2

correlati: http://stackoverflow.com/questions/3909267/differences-between-action-and- actionlistener/3909382 # 3909382 – BalusC

risposta

14

Ti vedo facilitare l'approccio tradizionale di Guess-come-funziona-utilizzando-bare-intuizione-e-random-associazioni-then-atto-sorpresa :-)

f:actionListener si lascia solo aggiungi un oggetto intero come osservatore, non un metodo arbitrario. È possibile utilizzare l'attributo type per specificare il nome della classe (verrà istanziato da JSF) o l'attributo binding per fornire un'istanza dell'oggetto creato dall'utente (non un metodo!). L'oggetto deve implementare javax.faces.event.ActionListener.

Il secondo tentativo (testDeviceGroupController.prepareCreate(event)) è errato su molti livelli, ma il punto cruciale è che i metodi sono chiamati a non gestire l'azione, ma a creare l'istanza Actionlistener.

Hai un paio di opzioni:

  • la più sana quello: basta fare un metodo che chiama ciascuno dei metodi di destinazione. Poiché sono su diversi fagioli, puoi iniettarne uno nell'altro.
  • se questo non funziona, puoi creare un metodo che crea un oggetto listener.

Ti piace questa:

public ActionListener createActionListener() { 
    return new ActionListener() { 
     @Override 
     public void processAction(ActionEvent event) throws AbortProcessingException { 
      System.out.println("here I have both the event object, and access to the enclosing bean"); 
     } 
    }; 
} 

e usarlo in questo modo:

<h:commandButton> 
    <f:actionListener binding="#{whateverBean.createActionListener()}"/>    
</h:commandButton> 
+0

Per rendere chiaro, perché * funziona? (L'ho usato prima quando ho bisogno di un solo bean) Crea oggetti listener out-of-the-box e chiama anyBean.actionListenerMethod? – smolarek999

+1

@ smolarek999: funziona, perché dovrebbe funzionare così ed è indicato nella documentazione! actionListenerMethod di commandbutton accetta un EL di un metodo da chiamare; e l'associazione actionlisteners accetta un EL di un oggetto ActionListener. Non puoi solo immaginare che due cose funzionano allo stesso modo solo perché il nome è simile. Davvero, indovinare è una cattiva, cattiva idea. – fdreger

+0

@fdreger Una spiegazione molto buona! – skuntsel

0

Il valore dell'attributo binding deve puntare a un oggetto che implementa l'interfaccia ActionListener, non un metodo.

Dalla documentazione dell'attributo f:actionListener s' bindig:

Valore espressione vincolante che restituisce un oggetto che implementa javax.faces.event.ActionListener.

Un problema simile è stato discusso here.