我有一个相当复杂的形式,表单字段的数量是flexibel.简而言之,模型对象是包含值(转换)的映射的TLabel(TranslationLabel).这里的语言是枚举,因此想法是给出翻译的字段(文本区域)的数量取决于此枚举中的值.
这是我的表格(简化):
公共类TranslationEditForm扩展Form {
private final static List<Language> LANGUAGES = newArrayList(Language.values());
public TranslationEditForm(String id, final TranslationLabelView label) {
super(id, new CompoundPropertyModel<TranslationLabelView>(label));
ListView<Language> textAreas = new ListView<Language>("translationRepeater", LANGUAGES) {
@Override
protected void populateItem(final ListItem<Language> itemLang) {
//loop through the languages and create 1 textarea per language
itemLang.add(new Label("language", itemLang.getModelObject().toString()));
Model<String> textModel = new Model<String>() {
@Override
public String getObject() {
//return the value for current language
return label.getValue(itemLang.getModelObject());
}
@Override
public void setObject(String object) {
//set the value for current language
label.getTranslations().put(itemLang.getModelObject(), object);
}
};
itemLang.add(new TextArea<String>("value", textModel).setRequired(true));
}
};
//add the repeater containing a textarea per language to the form
this.add(textAreas);
}
}
Run Code Online (Sandbox Code Playgroud)
现在,它工作正常,每种语言创建1个文本区域,其值也设置得很好; 更改时,模型会按预期更新.
如果您在清空文本区域后提交表单(因此最初有一个值),那么当然存在验证错误(必需).正常(wicket)行为将是无效字段仍为空但由于某种原因原始值被重置,我不明白为什么.
如果我像这样重写onError:
@Override
protected void onError() {
this.updateFormComponentModels();
}
Run Code Online (Sandbox Code Playgroud)
那么没关系,该字段的值设置为提交的值(空)而不是原始值.
知道是什么导致了这个吗?什么是wicket未能做到,因为我设置表单的方式(因为使用简单的表单/模型,这是正常工作的wicket示例)?
发布为答案,因此问题可以标记为已解决:
ListView确实在渲染时重新创建其所有项目.这意味着验证将被破坏.看看ListView的API文档
在ListView上调用setReuseItems()解决了这个问题.
此致,伯特