好像每次学习一个新平台,都得重新解决这个同样的老问题:
使用 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); 


评论关闭
IT干货网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!