好像每次学习一个新平台,都得重新解决这个同样的老问题:
使用 Ajax 在更改另一个下拉列表时更新一个下拉列表中的选项。这次
框架是 Wicket。
我有两个实体,我将称之为 Foo 和 Bar,每个 Foo 都有一个类别,它是 Foo 内部的枚举。此外,还有一个 FooDAO 重载 find()
方法:无参数版本返回数据库中的所有 Foo,或者带有类型 Foo 的参数“过滤器”的版本返回非空值中的所有 Foo 匹配过滤器。
客户端希望在创建新 Bar 时将 Foos 与 Bars 相关联,但在添加 Foos 之前要按类别过滤 Foos。所以假设一些 Foo 已经存在,每个都有一个类别。用户转到 create Bar 页面和添加新 Foo 的部分:Dropdown A 列出了类别,并且在选择了类别后,Dropdown B 应该通过 Ajax 更新显示该类别中可用 Foo 的列表。请注意,未选择任何类别,下拉列表 B 应显示所有可用的 Foo。
我的 HTML 看起来有点像这样:
<form wicket:id="createBarForm">
<div>
<label>Category</label>
<select wicket:id="category">
</select>
</div>
<div>
<label>Available Foo(s)</label>
<select class="xlarge" wicket:id="selectedFoo">
</select>
</div>
<button style="float:right;">Add</button>
<!-- and more Bar related fields -->
</form>
(按钮最终将获得自己的 id 和行为,但现在重点是列表。)
这是 Java 端(在页面的构造函数方法中):
createBarForm = new Form<Bar>("createBarForm",
new CompoundPropertyModel<Bar>());
final List<Foo> availableFoo = fooDao.find();
final FormComponent<Foo> selectedFoo =
new DropDownChoice<Foo>("selectedFoo",
Model.of(new TechnologyFoo()), availableFoo);
Foo.Category categoryStandin = null;
final FormComponent<Foo.Category> fooCategory =
new DropDownChoice<Foo.Category>
("fooCategory", Model.of(categoryStandin),
Arrays.asList(Foo.Category.values()));
fooCategory.add(new AjaxFormComponentUpdatingBehavior("onchange") {
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target) {
// re-set the form component
availableFoo.clear();
((DropDownChoice<Foo>)selectedFoo).setChoices(availableFoo);
createBarForm.remove(selectedFoo);
Foo.Category newSelection =
fooCategory.getModelObject();
if (newSelection != null) {
Foo filter = new Foo();
filter.setCategory(newSelection);
availableFoo.addAll(fooDao.find(filter));
}
else {
availableFoo.addAll(fooDao.find());
}
// re-fresh the form component
((DropDownChoice<Foo>)selectedFoo).setChoices(availableFoo);
createBarForm.add(selectedFoo);
}
});
createBarForm.add(fooCategory);
createBarForm.add(selectedFoo);
// etc.....
我还没有展示我的
logger.debug
调用,但通过它们我可以证明
newSelection
正在被正确捕获,并且 DAO 正在返回预期的 Foo 列表。另外,
avaliableFoo
List 也包含所需的值。然而,下拉 B 总是显示 Foo 的完整列表,不管
的类别选择。
请您参考如下方法:
您必须将 DropDowns 添加到 AjaxRequestTarget 中,否则它们将不会更新。
如
target.add(selectedFoo);