Jsf Primefaces Dependent SelectCheckBox带有全局集合的菜单

Jsf Primefaces Dependent SelectCheckBox带有全局集合的菜单,jsf,primefaces,jsf-2.2,Jsf,Primefaces,Jsf 2.2,我有两个下拉列表:一个是使用selectOneMenu组件实现的,另一个是使用selectCheckboxMenu实现的 在selectOneMenu中选择选项时,selectCheckboxMenu的选项值会根据selectOneMenu中选择的选项进行更新 发生以下情况: 我选择SelectOne菜单的一个选项,SelectCheckBox菜单就会被填充 我选择/检查SelectCheckBox菜单的一些选项 我选择SelectOne菜单的另一个选项,SelectCheckBox菜单将填充其

我有两个下拉列表:一个是使用selectOneMenu组件实现的,另一个是使用selectCheckboxMenu实现的

在selectOneMenu中选择选项时,selectCheckboxMenu的选项值会根据selectOneMenu中选择的选项进行更新

发生以下情况:

  • 我选择SelectOne菜单的一个选项,SelectCheckBox菜单就会被填充
  • 我选择/检查SelectCheckBox菜单的一些选项
  • 我选择SelectOne菜单的另一个选项,SelectCheckBox菜单将填充其他值
  • 我选择了一些新值
  • 我在SelectOne菜单的步骤1中选择该选项
  • 不再选择我在步骤2中选择的值
  • 我相信这是因为绑定到selectCheckboxMenu的列表值被setter方法重置了

    我想全局保存SelectCheckBox菜单的状态。这样做的最佳策略是什么

    编辑:

    以下是复制先前行为的相关代码:

    豆子:

    import javax.annotation.PostConstruct;
    导入javax.faces.bean.ManagedBean;
    导入javax.faces.bean.ViewScoped;
    导入javax.inject.inject;
    导入java.util.ArrayList;
    导入java.util.List;
    @ManagedBean
    @视域
    公共类BackingBean{
    private List parents=new ArrayList();
    private List children=new ArrayList();
    private List selectedChildren=new ArrayList();
    私有父级selectedParent=新父级();
    @注入
    家庭服务;
    @施工后
    公共void init(){
    parents=service.findParents();
    }
    已更改的公共项(){
    children=newarraylist();
    如果(getSelectedParent()==null){
    返回;
    }
    children=service.findChildrenByParent(getSelectedParent());
    }
    已选择的公共作废已更改(){
    System.out.println(selectedChildren.size());
    }
    公共列表getParents(){
    返回父母;
    }
    公共父对象(列出父对象){
    这个。父母=父母;
    }
    公共列表getChildren(){
    返回儿童;
    }
    公共子项(列出子项){
    这个。孩子=孩子;
    }
    公共列表getSelectedChildren(){
    返回所选的子项;
    }
    public void setSelectedChildren(列出selectedChildren){
    this.selectedChildren=selectedChildren;
    }
    公共父项getSelectedParent(){
    返回所选的父项;
    }
    public void setSelectedParent(Parent selectedParent){
    this.selectedParent=selectedParent;
    }
    }
    
    XHTML:

    <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:p="http://primefaces.org/ui">
    <h:head></h:head>
    <h:body>
    <h:form id="selectOne">
        <p:messages autoUpdate="true" />
    
            <h:outputLabel for="parents" value="Parents:" />
            <p:selectOneMenu converter="#{parentConverter}" id="parents" value="#{backingBean.selectedParent}">
                <p:ajax update="children" listener="#{backingBean.parentChanged}" />
                <f:selectItem noSelectionOption="true" value="#{null}" itemLabel="None" />
                <f:selectItems value="#{backingBean.parents}" var="p" itemLabel="#{p.name}" itemValue="#{p}" />
            </p:selectOneMenu>
    
    
            <h:outputLabel for="children" value="Children:" />
    
            <p:selectCheckboxMenu converter="#{childConverter}"  id="children"
                                  value="#{backingBean.selectedChildren}"
                                  label="Children" filter="true" filterMatchMode="startsWith">
                <p:ajax update="display" listener="#{backingBean.selectedSonChanged}" />
                <f:selectItems value="#{backingBean.children}" var="c" itemLabel="#{c.name}" itemValue="#{c}" />
            </p:selectCheckboxMenu>
    
    
            <p:outputPanel id="display">
                <p:dataList value="#{backingBean.selectedChildren}" var="sn" emptyMessage="No children selected">
                    #{sn.name}
                </p:dataList>
            </p:outputPanel>
    
            <p:commandButton value="Submit" update="display, selectOne" />
    
    </h:form>
    
    </h:body>
    </html>
    
    <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:p="http://primefaces.org/ui">
    <h:head></h:head>
    <h:body>
    <h:form id="selectOne">
        <p:messages autoUpdate="true" />
    
            <h:outputLabel for="parents" value="Parents:" />
            <p:selectOneMenu converter="#{parentConverter}" id="parents" value="#{backingBean.selectedParent}">
                <p:ajax update="children" listener="#{backingBean.parentChanged}" />
                <f:selectItem noSelectionOption="true" value="#{null}" itemLabel="None" />
                <f:selectItems value="#{backingBean.parents}" var="p" itemLabel="#{p.name}" itemValue="#{p}" />
            </p:selectOneMenu>
    
    
            <h:outputLabel for="children" value="Children:" />
    
            <p:selectCheckboxMenu converter="#{childConverter}"  id="children"
                                  value="#{backingBean.selectedChildren}"
                                  label="Children" filter="true" filterMatchMode="startsWith">
                <p:ajax update="display" listener="#{backingBean.selectedSonChanged}" />
                <f:selectItems value="#{backingBean.children}" var="c" itemLabel="#{c.name}" itemValue="#{c}" />
            </p:selectCheckboxMenu>
    
    
            <p:outputPanel id="display">
                <p:dataList value="#{backingBean.globalSelectedChildren}" var="sn" emptyMessage="No children selected">
                    #{sn.name}
                </p:dataList>
            </p:outputPanel>
    
            <p:commandButton value="Submit" update="display, selectOne" />
    
    </h:form>
    
    </h:body>
    </html>
    
    
    #{sn.name}
    
    完整的项目如下:

    您可以在此处找到前面提到的互动视频:

    正如您所看到的,当选择另一个“父项”,然后选择其子项时,前面的子项列表将被替换。如何正确修改此行为,使以前选择的元素保持不变并在SelectCheckBox菜单中显示为选中状态

    编辑2:

    我发现的一个解决方案是引入另一个变量,该变量将保存全局值,并将在侦听器方法“selectedsonchange”中进行修改。以下是相关代码:

    import javax.annotation.PostConstruct;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ViewScoped;
    import javax.inject.Inject;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.stream.Collectors;
    
    @ManagedBean
    @ViewScoped
    public class BackingBean {
    
        private List<Parent> parents = new ArrayList<>();
        private List<Child> children = new ArrayList<>();
        private List<Child> selectedChildren = new ArrayList<>();
    
        private List<Child> globalSelectedChildren = new ArrayList<>();
        private Parent selectedParent = new Parent();
    
        @Inject
        FamilyService service;
    
        @PostConstruct
        public void init(){
            parents = service.findParents();
        }
    
    
        public void parentChanged(){
            children = new ArrayList<>();
            if(getSelectedParent() == null){
                return;
            }
    
            children = service.findChildrenByParent(getSelectedParent());
            selectedChildren = globalSelectedChildren.stream().filter(c -> c.getParent().equals(selectedParent)).collect(Collectors.toList());
            System.out.println(selectedChildren.size());
        }
    
        public void selectedSonChanged(){
            System.out.println(selectedChildren.size());
            globalSelectedChildren = globalSelectedChildren.stream().filter(c -> !c.getParent().equals(selectedParent)).collect(Collectors.toList());
            globalSelectedChildren.addAll(selectedChildren);
        }
    
        public List<Parent> getParents() {
            return parents;
        }
    
        public void setParents(List<Parent> parents) {
            this.parents = parents;
        }
    
        public List<Child> getChildren() {
            return children;
        }
    
        public void setChildren(List<Child> children) {
            this.children = children;
        }
    
        public List<Child> getSelectedChildren() {
            return selectedChildren;
        }
    
        public void setSelectedChildren(List<Child> selectedChildren) {
            this.selectedChildren = selectedChildren;
        }
    
        public Parent getSelectedParent() {
            return selectedParent;
        }
    
        public void setSelectedParent(Parent selectedParent) {
            this.selectedParent = selectedParent;
        }
    
        public List<Child> getGlobalSelectedChildren() {
            return globalSelectedChildren;
        }
    
        public void setGlobalSelectedChildren(List<Child> globalSelectedChildren) {
            this.globalSelectedChildren = globalSelectedChildren;
        }
    }
    
    import javax.annotation.PostConstruct;
    导入javax.faces.bean.ManagedBean;
    导入javax.faces.bean.ViewScoped;
    导入javax.inject.inject;
    导入java.util.ArrayList;
    导入java.util.List;
    导入java.util.stream.collector;
    @ManagedBean
    @视域
    公共类BackingBean{
    private List parents=new ArrayList();
    private List children=new ArrayList();
    private List selectedChildren=new ArrayList();
    private List globalSelectedChildren=new ArrayList();
    私有父级selectedParent=新父级();
    @注入
    家庭服务;
    @施工后
    公共void init(){
    parents=service.findParents();
    }
    已更改的公共项(){
    children=newarraylist();
    如果(getSelectedParent()==null){
    返回;
    }
    children=service.findChildrenByParent(getSelectedParent());
    selectedChildren=globalSelectedChildren.stream().filter(c->c.getParent().equals(selectedParent)).collect(Collectors.toList());
    System.out.println(selectedChildren.size());
    }
    已选择的公共作废已更改(){
    System.out.println(selectedChildren.size());
    globalSelectedChildren=globalSelectedChildren.stream().filter(c->!c.getParent().equals(selectedParent)).collect(Collectors.toList());
    globalSelectedChildren.addAll(selectedChildren);
    }
    公共列表getParents(){
    返回父母;
    }
    公共父对象(列出父对象){
    这个。父母=父母;
    }
    公共列表getChildren(){
    返回儿童;
    }
    公共子项(列出子项){
    这个。孩子=孩子;
    }
    公共列表getSelectedChildren(){
    返回所选的子项;
    }
    public void setSelectedChildren(列出selectedChildren){
    this.selectedChildren=selectedChildren;
    }
    公共父项getSelectedParent(){
    返回所选的父项;
    }
    public void setSelectedParent(Parent selectedParent){
    this.selectedParent=selectedParent;
    }
    公共列表getGlobalSelectedChildren(){
    返回globalSelectedChildren;
    }
    public void setGlobalSelectedChildren(列出globalSelectedChildren){
    this.globalSelectedChildren=globalSelectedChildren;
    }
    }
    
    XHTML:

    <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:p="http://primefaces.org/ui">
    <h:head></h:head>
    <h:body>
    <h:form id="selectOne">
        <p:messages autoUpdate="true" />
    
            <h:outputLabel for="parents" value="Parents:" />
            <p:selectOneMenu converter="#{parentConverter}" id="parents" value="#{backingBean.selectedParent}">
                <p:ajax update="children" listener="#{backingBean.parentChanged}" />
                <f:selectItem noSelectionOption="true" value="#{null}" itemLabel="None" />
                <f:selectItems value="#{backingBean.parents}" var="p" itemLabel="#{p.name}" itemValue="#{p}" />
            </p:selectOneMenu>
    
    
            <h:outputLabel for="children" value="Children:" />
    
            <p:selectCheckboxMenu converter="#{childConverter}"  id="children"
                                  value="#{backingBean.selectedChildren}"
                                  label="Children" filter="true" filterMatchMode="startsWith">
                <p:ajax update="display" listener="#{backingBean.selectedSonChanged}" />
                <f:selectItems value="#{backingBean.children}" var="c" itemLabel="#{c.name}" itemValue="#{c}" />
            </p:selectCheckboxMenu>
    
    
            <p:outputPanel id="display">
                <p:dataList value="#{backingBean.selectedChildren}" var="sn" emptyMessage="No children selected">
                    #{sn.name}
                </p:dataList>
            </p:outputPanel>
    
            <p:commandButton value="Submit" update="display, selectOne" />
    
    </h:form>
    
    </h:body>
    </html>
    
    <html xmlns="http://www.w3.org/1999/xhtml"
            xmlns:f="http://java.sun.com/jsf/core"
            xmlns:h="http://java.sun.com/jsf/html"
            xmlns:p="http://primefaces.org/ui">
    <h:head></h:head>
    <h:body>
    <h:form id="selectOne">
        <p:messages autoUpdate="true" />
    
            <h:outputLabel for="parents" value="Parents:" />
            <p:selectOneMenu converter="#{parentConverter}" id="parents" value="#{backingBean.selectedParent}">
                <p:ajax update="children" listener="#{backingBean.parentChanged}" />
                <f:selectItem noSelectionOption="true" value="#{null}" itemLabel="None" />
                <f:selectItems value="#{backingBean.parents}" var="p" itemLabel="#{p.name}" itemValue="#{p}" />
            </p:selectOneMenu>
    
    
            <h:outputLabel for="children" value="Children:" />
    
            <p:selectCheckboxMenu converter="#{childConverter}"  id="children"
                                  value="#{backingBean.selectedChildren}"
                                  label="Children" filter="true" filterMatchMode="startsWith">
                <p:ajax update="display" listener="#{backingBean.selectedSonChanged}" />
                <f:selectItems value="#{backingBean.children}" var="c" itemLabel="#{c.name}" itemValue="#{c}" />
            </p:selectCheckboxMenu>
    
    
            <p:outputPanel id="display">
                <p:dataList value="#{backingBean.globalSelectedChildren}" var="sn" emptyMessage="No children selected">
                    #{sn.name}
                </p:dataList>
            </p:outputPanel>
    
            <p:commandButton value="Submit" update="display, selectOne" />
    
    </h:form>
    
    </h:body>
    </html>