2011-10-11 65 views

回答

4

执行此类操作的常用方法是通过AJAX。您可以轻松地将AJAX行为添加到第一个DropDownChoice,以填充/刷新第二个DropDownChoice的选项。

假设您使用IModel s来获得DropDownChoice s的选择。获得第二个DropDownChoice的选项的IModel将使用第一个DropDownChoice的ModelObject(因为它是依赖的)。

private DropDownChoice ddcCountry; 
private DropDownChoice ddcCity; 
//... 

IModel countriesModel = new LoadableDetachableModel(){ 
    @Override 
    protected Object load() { 
     return myService.getCountries(); 
    } 
}; 
IModel citiesModel = new LoadableDetachableModel(){ 
    @Override 
    protected Object load() { 
     if (ddcCountry.getModelObject() != null){ 
      return myService.getCities(ddcCountry.getModelObject()); 
     } 
     else { return new ArrayList(); } 
    } 
}; 
ddcCountry = new DropDownChoice("country", null, countriesModel); 
ddcCity = new DropDownChoice("city", null, citiesModel); 

您可以将一个AjaxFormComponentUpdatingBehavior到第一DropDownChoice。这将在<select>标记上输出一个onchange HTML事件处理程序,以便它将使用所选值更新该DropDownChoice的模型对象,然后将调用行为的onUpdate()。在onUpdate()方法中,您只需将第二个DropDownChoice添加到AjaxRequestTarget,并通过带有更新选项的ajax响应将其写回。请记住在将要添加到AjaxRequestTarget的所有组件上使用setOutputMarkupId(true)

例如,对于国家和城市2种依赖的选择:

ddcCity.setOutputMarkupId(true); 
ddcCountry.add(new AjaxFormComponentUpdatingBehavior(){ 
    @Override 
    protected void onUpdate(AjaxRequestTarget target) { 
     // here, ddcCountry's ModelObject has been already updated. 
     ddcCity.setModelObject(null); // clear selection 
     if (target != null) { 
      // Adding the ddc to the AjaxRequestTarget will write 
      // it back to the ajax response with new options pulled 
      // from the choices model. 
      target.addComponent(ddcCity); 
     } 
    } 
} 

如果你不使用IModels为你的选择(即使用在构造List对象),你只需要在onUpdate方法中获得新的List,并将其设置为ddcCitysetChoices()。您可以使用getComponent()方法获得Component的行为。如果你想支持没有JavaScript的用户

protected void onUpdate(AjaxRequestTarget target) { 
    // here, ddcCountry's ModelObject has been already updated. 
    List cities = myService.getCities(getComponent().getModelObject()); 
    ddcCity.setChoices(cities); 
    ddcCity.setModelObject(null); // clear selection 
    if (target != null) { 
     target.addComponent(ddcCity); 
    } 
} 

,你应该从默认禁用处理添加一个提交按钮(也许在一个<noscript>标签?),并且按钮的onSubmit执行相同的逻辑。

有关其他参考,请参阅DropDownChoice Examples Wicket wiki页面,您可能会发现“Ajax”部分有趣。

+0

非常感谢您的完整答案,我是Wicket的粉丝! :-) –

+0

@NoushinKhaki很高兴这是有用的:-)在这个例子中,也许'DropDownChoices'作为'私人'成员不是最好的选择。此外,你应该在你的'Page' /'Component' detach()'上为它们中的每一个调用'detach()',以便分离'LoadableDetachableModel'选项并避免让它们在PageMap中被序列化。 –