Калитка — отображение модального окна с компонентами формы в событии AjaxSelfUpdatingTimerBehavior не заполняет выбор пользователя

У меня есть ситуация, когда я пытаюсь отобразить форму ввода в Wicket 6 ModalWindow.

В настоящее время это очень простая форма с тремя переключателями в группе для того, чтобы все заработало.

// in TestPanel.class, the content of TestDialog:
protected void onInitialize() {
  super.onInitialize();

  RadioGroup<Integer> group = new RadioGroup<Integer>( "group", _model );
  getForm().add( group );

  group.add( new AjaxRadio<Integer>( "g1", Model.of( 1 ) ) {

    private static final long serialVersionUID = 1L;

    @Override
    protected void onInputChanged( AjaxRequestTarget target ) {
      System.out.println( getMarkupId() + " clicked, Input is now " + _model.getObject() );
    }      
  });
  // + 2 more other similar radio buttons..
}

(AjaxRadio — это просто Radio с добавленным AjaxEventBehavior("onchange"), который находит родительскую радиогруппу и вызывает group.processInput, за которым следует onInputChanged)

Если я покажу это диалоговое окно при нормальных обстоятельствах (например, onClick на AjaxLink), диалоговое окно отображается нормально, и модель корректно обновляется.

actionsForm.add( new AjaxLink<Object>( "link" ) {

  private static final long serialVersionUID = 1L;

  @Override
  public void onClick( AjaxRequestTarget target ) {
    TestDialog dialog = getDialog( TestDialog.class, target );
    dialog.show( target );
  }
} );

g1182 clicked, Input is now 1
g2183 clicked, Input is now 2
g3184 clicked, Input is now 3

Если я покажу диалоговое окно в AjaxSelfUpdatingTimerBehavior.onPostProcessTarget, модели компонентов формы никогда не обновляются!

  protected void onInitialize() {
    super.onInitialize();

    add( new AjaxSelfUpdatingTimerBehavior( Duration.ONE_SECOND ) {

      private static final long serialVersionUID = 1L;

      @Override
      protected void onPostProcessTarget( AjaxRequestTarget target ) {

        if( displayDialog() && dialogNotDisplayedYet() ) {
          TestDialog dialog = getDialog( TestDialog.class, target );
          dialog.show( target );
        }
      }
    });
  }

getDialog создает ModalWindows и добавляет их в дерево компонентов. Я пробовал добавлять диалоги по мере необходимости (как указано выше) или создавать диалог во время onInitialize, а затем просто показывать в onPostProcessTarget. Не имеет значения.

g1182 clicked, Input is now null
g2183 clicked, Input is now null
g3184 clicked, Input is now null

Я использую калитку 6.19.0 и Java 7.

причина реализации — я буду выполнять длинную задачу импорта, которая может время от времени задавать пользователю вопрос, поэтому поведение будет сканировать вопросы и представлять диалоговое окно, пока задача ожидает ответа.

Пожалуйста, кто-нибудь может помочь мне с этим?


person fancyplants    schedule 12.01.2016    source источник
comment
Проверьте, есть ли параметр запроса для имени/значения радио в вызове Ajax. Также попробуйте остановить поведение таймера при открытом диалоговом окне и перезапустить его после закрытия диалогового окна.   -  person martin-g    schedule 12.01.2016
comment
Не уверен, какие параметры вы имеете в виду - я проверил target.getPageParameters().getNamedKeys(), и в обеих ситуациях он был пуст.   -  person fancyplants    schedule 13.01.2016


Ответы (1)


Нашел проблему.

По сути, это не удастся в любой ситуации, когда на экране есть AjaxSelfUpdatingTimerBehavior. Это связано с тем, что реализация onTimer добавляет компонент к цели независимо от того, что я не хотел делать, поскольку это сбрасывает все входные данные. Поскольку его продолжительность составляла 1 секунду, не было возможности закрыть диалоговое окно после выбора варианта до того, как все снова будет сброшено.

Если я заменю его на AbstractAjaxTimerBehavior, все будет работать нормально, хотя я думаю, что позже могут возникнуть проблемы, когда мне нужно остановить таймер.

person fancyplants    schedule 13.01.2016
comment
Верно. AjaxSelfUpdatingTimerBehavior всегда будет обновлять компонент, к которому он подключен, с заданным интервалом, в то время как его метод onPostProcessTarget предоставляет перехватчик для дополнительной логики обновления. Если вы хотите остановить AbstractAjaxTimerBehavior, просто сохраните экземпляр в переменной и вызовите для него behavior.stop(); или вызовите this.stop(); из метода onTimer. - person Imperative; 13.01.2016