2013-05-04 22 views
6

Tôi muốn sử dụng nhiều người nghe hành động để thiết lập trạng thái của hai đậu ủng hộ trước khi tiếp tục xử lýNhiều actionlisteners trong JSF

cách 1:

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

Nó đưa ra một ngoại lệ:

CẢNH BÁO : /testGroup/List.xhtml @ 26,88 binding = "# {testController.nodeListener()}": Phương thức nodeListener không tìm thấy javax.el.ELException: /testGroup/List.xhtml @ 26,88 binding = "# { testController.nodeListen er()} ": Phương pháp nodeListener không tìm thấy

Cách 2:

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

tổ chức sự kiện là null trên nodeListener và prepareCreate phương pháp

Làm thế nào để làm điều đó có đúng không?

+2

liên quan: http://stackoverflow.com/questions/3909267/differences-between-action-and- actionlistener/3909382 # 3909382 – BalusC

Trả lời

14

Tôi thấy bạn thuận lợi cho việc tiếp cận truyền thống của đoán quyết-it-tác phẩm-sử dụng-trần-trực giác-and-ngẫu nhiên hiệp hội-then-hành-ngạc nhiên :-)

f:actionListener chỉ cho phép bạn thêm toàn bộ đối tượng làm người quan sát, không phải là phương pháp tùy ý. Bạn có thể sử dụng thuộc tính type để chỉ định tên lớp (nó sẽ được khởi tạo bởi JSF) hoặc thuộc tính binding để cung cấp cho một cá thể của đối tượng mà bạn đã tự tạo (không phải phương thức!). Đối tượng phải triển khai javax.faces.event.ActionListener.

Thử thứ hai của bạn (testDeviceGroupController.prepareCreate(event)) là sai ở nhiều cấp độ, nhưng mấu chốt là các phương thức được gọi là không xử lý hành động của bạn, nhưng để tạo cá thể Actionlistener.

Bạn có một vài lựa chọn:

  • các Sanest một: chỉ cần thực hiện một phương pháp mà các cuộc gọi mỗi người trong số các phương pháp mục tiêu. Vì chúng ở trên các loại đậu khác nhau, bạn có thể tiêm một cái khác.
  • nếu cách đó không hiệu quả với bạn, bạn có thể tạo phương thức tạo đối tượng người nghe.

Như thế này:

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

và sử dụng nó như thế này:

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

Để làm rõ, tại sao * làm việc? (Tôi sử dụng nó trước khi tôi chỉ cần onebean) Nó tạo ra đối tượng nghe out-of-the-box và hơn gọi anyBean.actionListenerMethod? – smolarek999

+1

@ smolarek999: nó hoạt động, bởi vì nó có nghĩa vụ phải làm việc như thế này và nó được nêu trong tài liệu! commandbutton's actionListenerMethod lấy một EL của một phương thức để gọi; và các actionlisteners binding lấy một EL của một đối tượng ActionListener. Bạn không thể đoán được rằng hai thứ hoạt động giống nhau chỉ vì tên giống nhau. Thực sự, đoán là một ý tưởng tồi tệ, xấu. – fdreger

+0

@fdreger Một lời giải thích rất tốt! – skuntsel

0

Giá trị thuộc tính binding cần trỏ đến đối tượng triển khai giao diện ActionListener, không phải phương thức.

Từ các tài liệu của bindig thuộc tính f:actionListener 's:

Giá trị ràng buộc biểu rằng kết quả là một đối tượng mà thực hiện javax.faces.event.ActionListener.

Sự cố tương tự đã được thảo luận here.