2013-05-04 16 views
6

chcę użyć wielu słuchacza działania określających stan dwóch ziaren podkładowych przed dalszym przetwarzaniemWiele actionlisteners w JSF

1st sposób:

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

dać wyjątek:

OSTRZEŻENIE : /testGroup/List.xhtml @ 26,88 binding = "# {testController.nodeListener()}": nie znaleziono metody nodeListener javax.el.ELException: /testGroup/List.xhtml @ 26,88 binding = "# { testController.nodeListen er()} ": Metoda nodeListener Nie znaleziono

2nd sposób:

<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> 

zdarzenie jest zerowy na nodeListener i prepareCreate metod

jak zrobić to prawidłowe?

+2

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

Odpowiedz

14

Widzę ułatwić tradycyjne podejście odgadnąć-how-to-prac wykorzystujących-nagim intuicji-and-losowych stowarzyszeń-then-ACT-zaskoczony :-)

f:actionListener tylko pozwala dodaj cały obiekt jako obserwator, a nie dowolną metodę. Możesz użyć atrybutu type, aby określić nazwę klasy (będzie to instancja JSF) lub binding, aby nadać instancję obiektu, który sam utworzyłeś (a nie metodą!). Obiekt musi implementować javax.faces.event.ActionListener.

Twoja druga próba (testDeviceGroupController.prepareCreate(event)) jest niepoprawna na wielu poziomach, ale sedno polega na tym, że metody te nie są obsługiwane, ale tworzą instancję Actionlistener.

Masz kilka opcji:

  • sanest jedno: po prostu zrobić metodę, która wywołuje każda z metod zwalczania. Ponieważ są one na różnych ziarnach, możesz wstrzykiwać je do siebie.
  • Jeśli to nie działa, możesz utworzyć metodę, która tworzy obiekt detektora.

Jak to:

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

i używać go tak:

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

Aby było jasne, dlaczego * działa? (Używałem go wcześniej, gdy potrzebuję tylko jednego bagaŜu) Tworzę obiekt detektora poza opakowaniem i wywołuję whatBean.actionListenerMethod? – smolarek999

+1

@ smolarek999: działa, ponieważ ma działać tak jak jest i jest to określone w dokumentacji! commandLutton's actionListenerMethod pobiera EL metody wywołania; i actionlisteners binding przyjmuje EL obiektu ActionListener. Nie możesz zgadnąć, że dwie rzeczy działają tak samo, ponieważ nazwa jest podobna. Naprawdę, zgadywanie to zły, zły pomysł. – fdreger

+0

@fdreger Bardzo dobre wyjaśnienie! – skuntsel

0

Wartość atrybutu binding musi wskazywać obiekt implementujący interfejs ActionListener, a nie metodę.

Z dokumentacji atrybutu f:actionListener „s bindig:

Wartość wiązania Wyrażenie, którego wartość obiektu, który implementuje javax.faces.event.ActionListener.

Podobny problem został omówiony here.