可能重复:
Primefaces selectOneMenu监听器未使用Strings 以外的对象调用
我正在将SelectItem
的List
创建为:
List<SelectItem> activityGlobalTypes = new ArrayList<SelectItem>();
for (ActivityTypeXMLModel activityTypeXMLModel : filteredActivityTypeXMLModels) {
activityGlobalTypes.add(new SelectItem(activityTypeXMLModel, activityTypeXMLModel.getParent()));
}
这是下拉菜单:
<p:selectOneMenu id="activityGlobalMenu" value="#{adminController.activityDTO.activityParentName}" required="true">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{adminController.activityGlobalTypes}" />
<p:ajax listener="#{adminController.updateDependentActivity}" />
</p:selectOneMenu>
现在从方法updateDependentActivity
public void updateDependentActivity(AjaxBehaviorEvent event) {
SelectOneMenu menu = (SelectOneMenu) event.getComponent();
System.out.println(menu.getValue());//it prints com.edfx.adb.xml.model.ActivityTypeXMLModel@7b6fe3c4
if(menu.getValue() instanceof ActivityTypeXMLModel) {
System.out.println("value is ActivityTypeXMLModel"); // I was expecting this one
} else if(menu.getValue() instanceof String) {
System.out.println("value is String"); //this line is executing
} else {
System.out.println("unknown");
}
}
我已经检查了SelectItem
的源代码,它以对象形式存储值。任何指针都会很有帮助。
关键是,您的问题是因为非标准Java对象(即没有JSF内置转换器的String
、Number
或Boolean
(默认情况下通过简单的Object#toString()
调用转换为String
。因此,复杂的对象最终在生成的HTML <option value>
中作为它们的toString()
表示。正是这个值被提交回服务器。
你可以用不同的方法来解决这个问题:
-
提供在
ActivityTypeXMLModel
和String
之间转换的自定义Converter
。这在以下问题中得到了回答:Primefaces selectOneMenu listener未使用Strings 以外的对象调用 -
如果您使用JSF实用程序库OmniFaces,那么您也可以使用提供的转换器
omnifaces.SelectItemsConverter
或omnifaces.SelectItemsIndexConverter
来执行基于<f:selectItem(s)>
值的通用转换,而无需编写自定义转换器。 -
不要提供复杂的Java对象类型作为项值,而是提供标准Java对象类型,如
String
。在您的情况下,您似乎想要使用ActivityTypeXMLModel
对象的activityParentName
属性。为了便于使用进行遍历,由于JSF2引入了<f:selectItems>
的var
属性,您只需要将值更改为List<ActivityTypeXMLModel>
而不是List<SelectItem>
。private List<ActivityTypeXMLModel> activityGlobalTypes;
带有
<f:selectItems value="#{adminController.activityGlobalTypes}" var="type" itemValue="#{type.activityParentName}" itemLabel="#{type.parent}" />
另请参阅:
- 我们的
selectOneMenu
wiki页面
adminController.activityDTO.activityParentName
是selectItem
还是字符串?也许,在这种情况下,它应该是一个selectItem。