似乎每次我学习一个新平台时,我都必须重新解决相同的老问题: 使用Ajax更改另一个下拉菜单时更新下拉菜单中的选项。这一次 的框架是Wicket。Wicket Ajax将其中一个下拉菜单更新为另一个下拉菜单
我有两个实体,我称之为Foo和Bar,每个Foo都有一个类别,这是Foo内部的枚举。此外,还有一个重载find()
方法的FooDAO:no-arg版本返回数据库中的所有Foo,或者带有类型Foo的参数“过滤器”的版本,它返回非空值中的所有Foo匹配过滤器。
客户希望在创建新Bar时将Foos与Bars关联,但在添加Fo之前按类别过滤Foos。因此,假设少数Foo已经存在,每个都有一个类别。用户转到创建栏页面并添加新的Foo部分:下拉列表中列出了类别,并且在选择某个类别时,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
列表也包含所需的值。但是,无论类别选择为 ,下拉B总是显示Foo的完整列表。
看到,因为你已经得到了正确的答案,这是阿里纳斯:我可能会移动选择/选择更新代码,在下拉菜单中选择组件各自的模型和公正在'onUpdate()'方法中调用'target.addComponent()'方法,你的代码将更容易阅读和维护。 – biziclop 2012-02-27 22:32:31