Primefaces依赖selectCheckboxMenu与全局集合

时间:2016-08-02 00:45:24

标签: jsf primefaces jsf-2.2

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

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

发生以下情况:

  1. 我选择了selectOneMenu的一个选项,selectCheckboxMenu被填充
  2. 我选择/检查selectCheckboxMenu的一些选项
  3. 我选择selectOneMenu的另一个选项,selectCheckboxMenu会填充其他值
  4. 我选择了一些新值
  5. 我选择了selectOneMenu
  6. 的第1步中的选项
  7. 不再选择我在步骤2中选择的值
  8. 我相信这是因为绑定到selectCheckboxMenu的列表值会被setter方法重置。

    我想要的是全局保存selectCheckboxMenu的状态。这样做的最佳策略是什么?

    编辑:

    这里是复制先前行为的相关代码:

    豆:

    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;
    
    @ManagedBean
    @ViewScoped
    public class BackingBean {
    
        private List<Parent> parents = new ArrayList<>();
        private List<Child> children = new ArrayList<>();
        private List<Child> selectedChildren = 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());
        }
    
        public void selectedSonChanged(){
            System.out.println(selectedChildren.size());
        }
    
        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;
        }
    }
    

    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>
    

    完整的项目在这里:https://github.com/cenobyte321/jsfsamples/tree/master/selectcheckboxmenu

    您可以在此处找到前面提到的互动视频: https://github.com/cenobyte321/jsfsamples/blob/master/selectcheckboxmenu/example1.mp4?raw=true

    正如您在选择另一个&#34; Parent&#34;时所看到的那样。然后选择他们的孩子,以前的子列表被替换。如何正确修改此行为,以便先前选择的元素在selectCheckboxMenu中保持并显示为已选中?

    编辑2:

    我找到的一个解决方案是引入另一个变量,该变量将保存全局值,并将在侦听器方法中进行修改&#34; selectedSonChanged&#34;。这是相关代码:

    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;
        }
    }
    

    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.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>
    

    以下是此解决方案的分支:https://github.com/cenobyte321/jsfsamples/tree/solution-1/selectcheckboxmenu

0 个答案:

没有答案
相关问题