如何仅在加载时为 SelectOneMenu 设置值?
How to set a value for SelectOneMenu only at loading?
使用 JSF,我试图做出一种复杂的情况(Class 名称已被重构,示例是极简主义的):
DB
关系:a guy
有 a car
,a car
有 a type
,a type
有 cars
selectOneMenu
为CarType
需要操作2个角色:
- 在loading
显示车辆类型
- 改变汽车提议时改变
当我加载我的 dataTable
时,对于每一行,我想显示汽车的价值,如果这个人有一辆(null
是一个有效的选择),并且在 selectOneMenu
for CarType
如果想要显示该人的汽车类型(如果该人有车的话),但我不能使用 guy.car.carType
因为我不想 write over 当改变它的值时,这个菜单也需要作为一个研究菜单:我选择一个类型,我可以看到它的汽车
一开始我不知道要使用哪个绑定来设置它的值
1. Classes
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>
3。豆子
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);
}
}
我宁愿:
在呈现视图之前加载您需要的所有内容:
<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
。有关详细信息,请参阅末尾的 link。
table 应该是这样的:
<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 -->
<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>
您不需要汽车选择中的侦听器,除非您想立即将该值保留在数据库中或基于此刷新页面中的任何其他部分。只需实现一个保存按钮并使其逻辑在被点击时保存所有 Map<Guy, Car>
值。
您还需要适当的 Type
和 Car
转换器。
另请参阅:
- Best way to add a "nothing selected" option to a selectOneMenu in JSF
- Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?
使用 JSF,我试图做出一种复杂的情况(Class 名称已被重构,示例是极简主义的):
DB
关系:a guy
有a car
,a car
有a type
,a type
有cars
selectOneMenu
为CarType
需要操作2个角色:
- 在loading 显示车辆类型
- 改变汽车提议时改变
当我加载我的 dataTable
时,对于每一行,我想显示汽车的价值,如果这个人有一辆(null
是一个有效的选择),并且在 selectOneMenu
for CarType
如果想要显示该人的汽车类型(如果该人有车的话),但我不能使用 guy.car.carType
因为我不想 write over 当改变它的值时,这个菜单也需要作为一个研究菜单:我选择一个类型,我可以看到它的汽车
一开始我不知道要使用哪个绑定来设置它的值
1. Classes
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>
3。豆子
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);
}
}
我宁愿:
在呈现视图之前加载您需要的所有内容:
<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
。有关详细信息,请参阅末尾的 link。
table 应该是这样的:
<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 -->
<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>
您不需要汽车选择中的侦听器,除非您想立即将该值保留在数据库中或基于此刷新页面中的任何其他部分。只需实现一个保存按钮并使其逻辑在被点击时保存所有 Map<Guy, Car>
值。
您还需要适当的 Type
和 Car
转换器。
另请参阅:
- Best way to add a "nothing selected" option to a selectOneMenu in JSF
- Conversion Error setting value for 'null Converter' - Why do I need a Converter in JSF?