代码之家  ›  专栏  ›  技术社区  ›  azro

如何仅在加载时为selectonemenu设置值?

  •  0
  • azro  · 技术社区  · 6 年前

    使用jsf,我试图制造一种复杂的情况(类名已经被重构,示例是极简的):

    • DB 关系: a guy a car , 一辆小汽车 a type , 一种 cars

    这个 selectOneMenu 对于 CarType 需要操作两个角色:

    • 显示车辆类型 加载
    • 改变汽车的主张

    当我装载 dataTable ,对于每一排,我想显示车的价值,如果他有一辆( null 是一个有效的选择)。 选择菜单 对于 卡式 如果想显示这个人的车的类型,如果那个家伙有一个,但是我不能用 guy.car.carType 因为我不想 写完 当更改其值时,此菜单还需要用作 研究 菜单:我选择一种类型,我可以看到它的汽车

    我不知道在开始时使用哪一个绑定来设置它的值。


    1。班

    class Guy{
        Car car;
    }
    class Car{
        CarType type;
    }
    class CarType{
        String type;
    }
    

    2。视图

    <p:dataTable value="#{Bean.guys}"  var="guy">
        <p:column>
            <p:selectOneMenu value="#{Bean.selectedType}>
                <f:selectItem value="#{null}" />
                <f:selectItems value="#{Beans.types}">
                <p:ajax event="change" listener="#{bean.changeType}" />
            </p:selectOneMenu>
        </p:column>
    
        <p:column>
            <p:selectOneMenu value="#{Bean.selectedCar}>
                <f:selectItem value="#{null}" />
                <f:selectItems value="#{Beans.cars(guy)}" />
                <p:ajax event="change" listener="#{bean.changeCar(guy)}" />
            </p:selectOneMenu>
        </p:column>
    
    </p:dataTable>
    

    三。菜豆

    class Bean{
        public List<Guy> guys;        // filled from DB
        public List<Car> cars;        // filled from DB
        public List<CarType> types;   // filled from DB
        private Car selectedCar;      // getter setter ok
        private CarType selectedType; // getter setter ok
    
        public List<Car> cars(Guy g){
            selectedCar = g.getCar();
            cars = selectedCar.getCarType().getCars(); // all cars of this type
        }
    
        public void changeType(){
            cars = selectedType.getCars();
        }
    
        public void changeCar(Guy g){
            g.setCar(selectedCar);
        }
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   Aritz    6 年前

    我宁愿:

    在呈现视图之前加载所需的所有内容:

    <f:metadata>
        <f:viewAction action="#{bean.onload}" />
    </f:metadata>
    
    public void onload(){
      //Here load all the guys and all the cars and make the associations for the cars per guy. 
      //Use the java structures you consider, do not limit to what you have in your model
    }
    

    更改数据模型。当你为每个人选择汽车,同时为每个人保留选定的类型时,你需要两张地图: Map<Guy, Type> type Map<Guy, Car> cars . 更多信息请参见末尾的链接。

    桌子应该是这样的:

    <p:dataTable value="#{bean.guys}" var="guy">
        <p:column>
            <p:selectOneMenu value="#{bean.type[guy]}">
                <f:selectItem value="#{null}" noSelectionOption="true" />
                <f:selectItems value="#{bean.allTypes}">
                <!-- This reloads only the cars menu for this guy -->
                <p:ajax event="change" listener="#{bean.typeChanged(guy)}" />
            </p:selectOneMenu>
        </p:column>
    
        <p:column>
            <!-- Use a map here, see https://stackoverflow.com/a/49653561/1199132 -->
            <p:selectOneMenu value="#{bean.car[guy]}>
                <f:selectItem value="#{null}" noSelectionOption="true" />
                <!-- Loads the car selection for the type selected for the guy -->
                <f:selectItems value="#{bean.availableCars(bean.type[guy])}" />
            </p:selectOneMenu>
        </p:column>
    
    </p:dataTable>
    

    您不需要在car选择中使用监听器,除非您希望立即将该值保存在db中,或者基于此刷新页面中的任何其他部分。只需实现一个save按钮并使其逻辑保存所有 Map<Guy, Car> 被击中时的值。

    你也需要适当的 Type Car 转换器。

    参见: