2012-01-16 28 views
2

我使用dateTimeField和ListView構建窗體。 的ListView看起來像這樣:Apache wicket:如何在驗證錯誤後更新模型

final ListView<String> countryView = new ListView<String>("country", model.<List<String>>bind("country")) { 
      @Override 
      protected void populateItem(final ListItem<String> item) { 
        final String country = item.getModelObject(); 
        item.add(new ValidationDisplayableLabel("country", country, new String[] { modelPath })); 
        item.add(new AjaxLink("deleteLink") { 
         @Override 
         public void onClick(AjaxRequestTarget target) { 
          model.getObject().getCountry().remove(country); 
          if (issPeriod) { 
           addButton.setVisible(true); 
           countryTextField.setVisible(true); 
           findButton.setVisible(true); 
          } 
          if (target != null) 
           target.addComponent(rowPanel); 
         } 
        }); 
      } 
     }; 
     countryTextField = new ValidationDisplayableTextField("countryCodeInput", model.bind("oneCountry"), "job.country.value"); 

     **countryView.setReuseItems(true);** 
     rowPanel.add(countryView); 
     rowPanel.add(countryTextField); 
     addButton.setOutputMarkupPlaceholderTag(true); 
     rowPanel.add(addButton); 

而且Add按鈕看起來像這樣:

AjaxSubmitLink addButton = new AjaxSubmitLink(LinkNames.addCountry.toString()) { 
     @Override 
     public void onSubmit(AjaxRequestTarget target, Form form) { 
      if (model.getObject().getOneCountry() != null) 
       addCountry(); 
       if (target != null) 
        target.addComponent(rowPanel); 
       target.addComponent(form.getPage().get("feedbackPanel")); 
     } 
     @Override 
     protected void onError(AjaxRequestTarget target, Form<?> form) 
     { 
      onSubmit(target, form); 
     } 
    }; 

的事情是,當我失敗我DateTimeField字段(如組個小時到100),在countryTextField輸入國家或地區代碼,然後按addButton,它將在反饋面板中顯示驗證消息,該小時範圍不正確,但不添加國家/地區。這是因爲我的模型沒有更新。也許有辦法手動更新它?所以驗證信息會顯示,但國家listView仍然可以更新?

整個表單的提交位於其他按鈕上,因此從邏輯上說,即使在dateTimeField中存在驗證錯誤,添加國家也是正常的。

謝謝!

P.S.我已經閱讀了很多關於類似問題的文章,但其中大部分都是用.setReuseItems(true)解決的,但在我的情況下它不起作用。

P.P.S阿帕奇檢票1.4.17

回答

5

我在我的項目面臨着類似的問題,我找到了解決方法是使用一種特殊的訪客。即使提交的輸入無效,它也會更新模型。

public class VisitorUpdateModelWithoutValidation implements FormComponent.IVisitor { 

public Object formComponent(IFormVisitorParticipant formComponent) { 
     if (formComponent instanceof FormComponent) { 
      final FormComponent<?> formComponent1 = (FormComponent<?>) formComponent; 
      boolean required = formComponent1.isRequired(); 
      if (required) { 
       formComponent1.setRequired(false); 
      } 
      formComponent1.modelChanging(); 
      formComponent1.validate(); 
      formComponent1.updateModel(); 
      formComponent1.modelChanged(); 
      if (required) { 
       formComponent1.setRequired(true); 
      } 
     } 

     return Component.IVisitor.CONTINUE_TRAVERSAL; 
    } 
} 

在你的行爲的onSubmit方法簡單地使用它:getForm().visitFormComponents(new VisitorUpdateModelWithoutValidation());

+1

對我來說,這感覺非常破碎,而不是你的代碼,但除非表單被驗證,否則那個檢票不會更新模型。 – 2012-06-19 18:53:00

+0

我看不到你的觀點。驗證器的目的是確保模型對象不包含無效數據。更新它們沒有多大意義。 – 2012-11-05 13:06:52

+0

模型更新限制僅在表單(通常)被提交時才重要。這種檢票行爲不僅限制了提交時的模型更新,而且還限制了其他任何事件。例如,我的複選框模型更新其他組件事件將永遠不會在驗證錯誤後在屏幕上顯示當前狀態。對我而言,這是一些「邪惡」的Wicket行爲。 – will824 2013-05-09 14:58:29

5

作爲更新這個答案,在檢票6,你可以通過在表格覆蓋的onError()實現這一點:

@Override 
    protected void onError() { 
    super.onError(); 
    this.updateFormComponentModels(); 
} 
+0

這對我來說非常有用。謝謝 – will824 2013-05-09 14:56:33

2

在定位更新之前,您可以在更新的字段上發出field.clearInput()