2011-06-07 46 views
1

此異常:java.lang.IllegalStateException:這種處理程序不能連接到多個組件

java.lang.IllegalStateException: this kind of handler cannot be attached to multiple components; it is already attached to component [MarkupContainer [Component id = textField1]], but component [MarkupContainer [Component id = textField2]] wants to be attached too 
at org.apache.wicket.behavior.AbstractAjaxBehavior.bind(AbstractAjaxBehavior.java:70) 
at org.apache.wicket.Component.add(Component.java:973) 
at info.ems.wicket.page.HomePage.<init>(HomePage.java:23) 

通過下面的代碼拋出:

public class HomePage extends MasterPage { 

    public HomePage() { 
     AjaxEventBehavior ajaxOnClickBehavior = new AjaxEventBehavior("onClick") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onEvent(AjaxRequestTarget target) { 
       // Same behavior of both the textField1 and textField2 
      } 
     }; 

     add(new TextField<String>("textField1", new Model<String>("Text Field 1")).add(ajaxOnClickBehavior)); 
     add(new TextField<String>("textField2", new Model<String>("Text Field 2")).add(ajaxOnClickBehavior));  
    } 
} 

但是,這是好的:

public class HomePage extends MasterPage { 

    public HomePage() { 
     add(new TextField<String>("textField1", new Model<String>("Text Field 1")).add(new AjaxEventBehavior("onClick") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onEvent(AjaxRequestTarget target) { 
       // Behavior of textField1, same as textField2 
      } 
     })); 
     add(new TextField<String>("textField2", new Model<String>("Text Field 2")).add(new AjaxEventBehavior("onClick") { 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onEvent(AjaxRequestTarget target) { 
       // Behavior of textField2, same as textField1 
      } 
     }));   
    } 
} 

爲什麼?

謝謝。

補充:

public class HomePage extends MasterPage { 

    public HomePage() { 
     add(new TextField<String>("textField1", new Model<String>("Text Field 1")).add(new AjaxOnClickBehavior("onClick"))); 
     add(new TextField<String>("textField2", new Model<String>("Text Field 2")).add(new AjaxOnClickBehavior("onClick"))); 
    } 

    private class AjaxOnClickBehavior extends AjaxEventBehavior { 

     private static final long serialVersionUID = 1L; 

     public AjaxOnClickBehavior(String event) { 
      super(event); 
     } 

     @Override 
     protected void onEvent(AjaxRequestTarget target) { 
      // Same behavior of both the textField1 and textField2 
     } 

    } 
} 

回答

6

基本上,你不能指定一個行爲到多個組件的同一個實例。如果你想提高可讀性和可維護性,你可以使用:

public class HomePage extends MasterPage { 
    public HomePage() { 
     add(new TextField<String>("textField1", new Model<String>("Text Field 1")).add(newOnClickBehavior())); 
     add(new TextField<String>("textField2", new Model<String>("Text Field 2")).add(newOnClickBehavior()));  
    } 

    protected AjaxEventBehavior newOnClickBehavior() { 
     return new AjaxEventBehavior("onClick") { 
      private static final long serialVersionUID = 1L; 

      @Override 
      protected void onEvent(AjaxRequestTarget target) { 
       // Same behavior of both the textField1 and textField2 
      } 
     }; 
    } 
} 
+4

或者甚至更好,如果您多次使用一個類,請將其轉換爲命名的內部類而不是匿名類。 – biziclop 2011-06-07 17:43:31

+0

@biziclop我已經添加了一個代碼。這是你提到的「命名的內部類而不是匿名的」嗎? – 2011-06-07 17:57:35

+0

@Tapas這正是他的意思。 – Marcelo 2011-06-07 18:31:02

3

一個Ajax行爲,因爲它的回調URL所依賴的組件連接到只是一個組成部分。否則,單擊ButtonB可能會執行ButtonA#onClick()