Замена калитки только на компоненте, добавленном к родительскому

Я получаю исключение из Wicket 1.4.11:

2010-11-03 17:44:51,971 [http-8080-1] ОШИБКА org.apache.wicket.RequestCycle — метод onFormSubmitted интерфейса org.apache.wicket.markup.html.form.IFormSubmitListener, предназначенный для компонента [MarkupContainer [Component id = customer]] вызвало исключение
org.apache.wicket.WicketRuntimeException: метод onFormSubmitted интерфейса
org.apache.wicket.markup.html.form.IFormSubmitListener, нацеленный на компонент [MarkupContainer [Component id = customer] ] вызвало исключение в org.apache.wicket.RequestListenerInterface.invoke(RequestListenerInterface.java:193)
...
Вызвано: java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...
Причина: java.lang.IllegalStateException: Этот метод можно вызывать только для компонента, который уже добавлен к его родительскому элементу.
в org.apache.wicket.Component. replaceWith(Component.java:2804)
по адресу no.magge.iumb.web.crm.cust omers.PrivateCustomerTab$1.onSubmit(PrivateCustomerTab.java:34)
в org.apache.wicket.markup.html.form.Form.delegateSubmit(Form.java:1565)

Это произошло, когда я щелкнул cancel_btn формы на панели панели вкладок в панели вкладок... Вот код для cancel_btn:

public class PrivateCustomerTab extends Panel {

 private static final long serialVersionUID = 16L;

 protected Panel getCurrentPanel() {
  return this;
 }

 public PrivateCustomerTab(String id, long customerId, final Panel backPanel) {
  super(id);

  final PrivateCustomerForm form = new PrivateCustomerForm("customer", customerId) {
   private static final long serialVersionUID = 4L;
   @Override
   protected void onSubmit() {
    System.out.println("\n\n(formsubmit) HELLO THERE MY PARENT IS: " + getParent() + "\n\n");
    if (customerId!=0) {
     PrivateCustomerTab.this.replaceWith(new PrivateCustomerTab("panel", customerId, backPanel));
    }
   }
  };
  add(form);

  Button cancelButton = new Button("cancel_btn", new ResourceModel("cancel")) {
   private static final long serialVersionUID = 18L;
   @Override
   public void onSubmit() {
    System.out.println("\n\n(cancelsubmit) HELLO THERE MY PARENT IS: " + getParent() + "\n\n");
    if (backPanel!=null) {
     // PrivateCustomerTab.this.replace(backPanel);
     getCurrentPanel().replaceWith(new CustomerListTab("panel"));

    }
   }
  };
  cancelButton.setVisible(backPanel!=null);
  form.add(cancelButton);
        }
}

Я пробовал разные способы получить текущую панель, которую я хочу заменить. Один из способов — использовать метод getCurrentPanel(), который просто возвращает this из класса панели. Другой способ — PrivateCustomerTab.this.replaceWith(...), и я также пробовал getParent().getParent().replaceWith(...). Все это дает мне сообщение о том, что я не могу заменить что-то, что не добавлено к его родителю.

Я думаю, что я, должно быть, неправильно понимаю здесь какую-то ключевую концепцию. Может быть, формы обрабатываются до того, как моя панель будет добавлена ​​к родительской, то есть я не могу заменить панель в cancel_btn на onSubmit()?

Я попытался погуглить по-своему и найти что-нибудь об этом в своем экземпляре Wicket in Action. Пожалуйста, помогите мне понять... спасибо!


person Magnus    schedule 03.11.2010    source источник


Ответы (2)


Дело не в том, чтобы найти правильную панель. Кажется, это нормально. Кажется, что все три вызова находят одну и ту же панель.

Речь идет о том, куда добавляется сама панель. Чтобы заменить себя чем-то другим, компонент должен спросить родителя, куда он был добавлен. Затем он просит своего родителя забыть о себе и выбрать данный Компонент в качестве дочернего.

Так что калитка в основном жалуется, что панель не добавляется ни к одному компоненту.

Изменилась ли за это время иерархия компонентов?

person mfunk    schedule 04.11.2010
comment
Нет, насколько я понимаю, иерархия не должна была измениться. У меня есть ссылка, которая replaceWith() и заменяет в этой панели PrivateCustomerTab. Я не меняю разметку и не делаю ничего, чтобы манипулировать иерархией между этим и методом onSubmit метода cancel_btn. - person Magnus; 04.11.2010
comment
Я понимаю, что вы говорите о том, что проблема в том, что моя панель теперь каким-то образом не имеет родителя. Так что спасибо вам за это... - person Magnus; 04.11.2010
comment
Отметил это как полезное. Нашел проблему и разместил ответ ниже. В очередной раз благодарим за помощь. - person Magnus; 04.11.2010

Я понял это - ошибка новичка (опять же).

Что происходит, так это то, что формы onSubmit() вызываются перед cancel_btn onSubmit(). Поскольку первый из этих методов заменяет панель, естественно, что при второй попытке заменить ту же панель она больше не добавляется к родителю.

Чтобы решить эту проблему, я переместил код формы onSubmit() в кнопки сохранения onSubmit(). При этом вызывается только 1 метод onSubmit(), в зависимости от того, какая кнопка была нажата.

person Magnus    schedule 04.11.2010
comment
Действительно? Как странно: Wicket сначала вызывает метод onSubmit кнопки, а затем (если не настроено иначе) вызывает метод onSubmit формы. - Калитка в действии, стр. 157. - person Pops; 06.11.2010
comment
Странный. Я дам ему еще один отладочный запуск. - person Magnus; 06.11.2010