我使用JSF2.0。我有三个下拉菜单:
- masterDropDown。
- childDropDownA
- childDropDownB
需要执行的业务规则是:
- 当masterDropDown发生变化时,我需要填充childDropDownA和childDropDownB。
- childDropDownA和childDropDownB的内容与相同,除了当用户从childDropDownA中选择内容时,childDropDownB应该保留其旧内容,除了用户在childDropDownA中选择的内容。当用户首先选择childDropDownB时,同样的规则也适用。
在JSF中实现这一点的最干净的方法是什么?
Plain JSF 2:
<h:form>
<h:selectOneMenu id="ddlMaster" value="#{bean.ddlMasterSelected}">
<f:listItems value="#{bean.ddlMasterData}" />
<f:ajax listener="#{bean.fillChildren}" render="ddlChildA ddlChildB" />
</h:selectOneMenu>
<h:selectOneMenu id="ddlChildA" value="#{bean.ddlChildASelected}">
<f:listItems value="#{bean.ddlChildAData}" />
<f:ajax listener="#{bean.refillChildB}" render="ddlChildB" />
</h:selectOneMenu>
<h:selectOneMenu id="ddlChildB" value="#{bean.ddlChildBSelected}">
<f:listItems value="#{bean.ddlChildBData}" />
<f:ajax listener="#{bean.refillChildA}" render="ddlChildA" />
</h:selectOneMenu>
</h:form>
托管bean
@ManagedBean
@ViewScoped
public class Bean {
private Map<String, String> ddlMasterData;
private Map<String, String> ddlChildAData;
private Map<String, String> ddlChildBData;
private String ddlMasterSelected;
private String ddlChildASelected;
private String ddlChildBSelected;
@PostConstruct
public void init() {
//fill initial values for the drop down lists...
//this is a raw idea, you must refine it
DDLService ddlService = new DDLService();
ddlMasterData = ddlService.getDDLMasterData();
//empty data for children ddls
ddlChildAData = new LinkedHashMap<String, String>();
ddlChildBData = new LinkedHashMap<String, String>();
}
public void refillChildB(AjaxBehaviorEvent event) {
//filling the children ddls
DDLService ddlService = new DDLService();
ddlChildASelected = ddlService.getDDLChildData();
//same method to fill child data on ddlChildBSelected because is same data
ddlChildBSelected = ddlService.getDDLChildData();
}
public void fillChildren(AjaxBehaviorEvent event) {
//when the user selects something from childDropDownA
//childDropDownB should have its old contents
//I assume it must be cleared, you can change this behavior though
ddlChildBData = new LinkedHashMap<String, String>();
}
public void refillChildA(AjaxBehaviorEvent event) {
//The same rule applies when the user selects childDropDownB first
//I assume it must be cleared, you can change this behavior though
ddlChildAData = new LinkedHashMap<String, String>();
}
}