Primefaces selectOneMenu 不显示初始值
Primefaces selectOneMenu not displaying initial value
我在 p:dialog
中设置了带有 POJO 和转换器的 selectOneMenu,请参阅下面的资源。它确实有效,除了最初,当它第一次以非下拉状态显示时,第一个选择是selected,而不是bean值对应的那个.如果我保存 selectOneMenu 的状态而不与之交互,最初 selected 的第一个选择被保存,因此实际值被覆盖,但是如果我 select 一个不同的选择,它被妥善保存。 selectOneMenu绑定的bean值不能是null
.
我调试了转换器,结果是加载后台数据和刷新显示对话框时,所有的选择都通过转换器的getAsString()
,加上真正的选择豆值再次。尽管如此,第一个选项实际上得到 selected 并显示在 selectOneMenu 中。当对话框的表单被提交时,实际 selected 选择通过转换器的 getAsObject()
,不管那是错误的 selected 初始值还是手动 selected .
请告知可能是什么问题。
调用对话框的按钮的 xhtml,这是另一种形式:
<p:commandButton id="toolbarEditButton"
value="Edit selected" update=":editMediaForm"
disabled="#{!contentManager.mediaSelected}"
actionListener="#{contentManager.editSelectedMedia}"
onclick="PF('editMediaWidget').show()" />
对话框的 xhtml:
<p:dialog id="editMediaDialog" widgetVar="editMediaWidget"
modal="true" resizable="false" >
<h:form id="editMediaForm" >
<p:panelGrid rendered="#{contentManager.isMediaSelected()}" columns="2" >
... <!-- other properties of the selected element -->
<p:outputLabel value="Media type" />
<p:selectOneMenu value="#{contentManager.selectedMedia.mediaType}"
converter="#{mediaTypeConverter}">
<f:selectItems value="#{mediaTypeConverter.allMediaTypes}"
var="mt" itemLabel="#{mt.name}" itemValue="#{mt}" />
<p:ajax listener="#{contentManager.onMediaTypeChanged()}" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</p:dialog>
转换器:
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String stringId) {
Long id = Long.valueOf(stringId);
for (MediaType mt : mediaTypes) {
if (mt.getPkid().equals(id)) {
return mt;
}
}
return null;
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object mtObj) {
MediaType mt = (MediaType) mtObj;
return mt.getPkid().toString();
}
public List<MediaType> getAllMediaTypes() {
return mediaTypes;
}
编辑:支持 bean
@SessionScoped // javax.enterprise.context.SessionScoped
@Named("contentManager") // javax.inject.Named
public class ContentManager implements Serializable {
...
private List<Media> mediaList;
private Media selectedMedia = null;
...
public boolean isMediaSelected() {
if (selectedMedia == null) return false;
return true;
}
...
public void saveSelectedMedia() {
myDao.saveMedia(selectedMedia);
}
public void editSelectedMedia() {
// only for debugging, could be removed
}
}
打开对话框并通过编辑按钮更新表单,该按钮仅在从数据表 (selectedMedia) selected 元素后可用。更新似乎确实有效,因为 selected 元素的其他属性已正确更新并显示在对话框中,因此 selectOneMenu 后面的 bean 值应该没问题。
更新:当然我也检查了生成的HTML。 <select>
对我来说似乎没问题,它包含要由转换器转换的正确值。 (selection还是错的)
<select id="form:blah_input" name="form:blah_input" tabindex="-1">
<option value="1" selected="selected">1 - half_horizontal</option>
<option value="2">2 - half_vertical</option>
<!-- etc -->
</select>
显示在 SelectOneMenu
中的对象必须有适当的 equals()
方法 ,而不仅仅是默认的 Object#equals
他们是同一个对象。这解释了为什么初始显示的值总是第一个:bean 值从未匹配任何可能的值,因此 SelectOneMenu
组件只显示第一个。
所以错误不在 JSF 或支持 bean 代码中,而在显示的域对象的 (MediaType) 代码中。在那里添加 equals() 方法解决了问题。
我在 p:dialog
中设置了带有 POJO 和转换器的 selectOneMenu,请参阅下面的资源。它确实有效,除了最初,当它第一次以非下拉状态显示时,第一个选择是selected,而不是bean值对应的那个.如果我保存 selectOneMenu 的状态而不与之交互,最初 selected 的第一个选择被保存,因此实际值被覆盖,但是如果我 select 一个不同的选择,它被妥善保存。 selectOneMenu绑定的bean值不能是null
.
我调试了转换器,结果是加载后台数据和刷新显示对话框时,所有的选择都通过转换器的getAsString()
,加上真正的选择豆值再次。尽管如此,第一个选项实际上得到 selected 并显示在 selectOneMenu 中。当对话框的表单被提交时,实际 selected 选择通过转换器的 getAsObject()
,不管那是错误的 selected 初始值还是手动 selected .
请告知可能是什么问题。
调用对话框的按钮的 xhtml,这是另一种形式:
<p:commandButton id="toolbarEditButton"
value="Edit selected" update=":editMediaForm"
disabled="#{!contentManager.mediaSelected}"
actionListener="#{contentManager.editSelectedMedia}"
onclick="PF('editMediaWidget').show()" />
对话框的 xhtml:
<p:dialog id="editMediaDialog" widgetVar="editMediaWidget"
modal="true" resizable="false" >
<h:form id="editMediaForm" >
<p:panelGrid rendered="#{contentManager.isMediaSelected()}" columns="2" >
... <!-- other properties of the selected element -->
<p:outputLabel value="Media type" />
<p:selectOneMenu value="#{contentManager.selectedMedia.mediaType}"
converter="#{mediaTypeConverter}">
<f:selectItems value="#{mediaTypeConverter.allMediaTypes}"
var="mt" itemLabel="#{mt.name}" itemValue="#{mt}" />
<p:ajax listener="#{contentManager.onMediaTypeChanged()}" />
</p:selectOneMenu>
</p:panelGrid>
</h:form>
</p:dialog>
转换器:
@Override
public Object getAsObject(FacesContext arg0, UIComponent arg1, String stringId) {
Long id = Long.valueOf(stringId);
for (MediaType mt : mediaTypes) {
if (mt.getPkid().equals(id)) {
return mt;
}
}
return null;
}
@Override
public String getAsString(FacesContext arg0, UIComponent arg1, Object mtObj) {
MediaType mt = (MediaType) mtObj;
return mt.getPkid().toString();
}
public List<MediaType> getAllMediaTypes() {
return mediaTypes;
}
编辑:支持 bean
@SessionScoped // javax.enterprise.context.SessionScoped
@Named("contentManager") // javax.inject.Named
public class ContentManager implements Serializable {
...
private List<Media> mediaList;
private Media selectedMedia = null;
...
public boolean isMediaSelected() {
if (selectedMedia == null) return false;
return true;
}
...
public void saveSelectedMedia() {
myDao.saveMedia(selectedMedia);
}
public void editSelectedMedia() {
// only for debugging, could be removed
}
}
打开对话框并通过编辑按钮更新表单,该按钮仅在从数据表 (selectedMedia) selected 元素后可用。更新似乎确实有效,因为 selected 元素的其他属性已正确更新并显示在对话框中,因此 selectOneMenu 后面的 bean 值应该没问题。
更新:当然我也检查了生成的HTML。 <select>
对我来说似乎没问题,它包含要由转换器转换的正确值。 (selection还是错的)
<select id="form:blah_input" name="form:blah_input" tabindex="-1">
<option value="1" selected="selected">1 - half_horizontal</option>
<option value="2">2 - half_vertical</option>
<!-- etc -->
</select>
显示在 SelectOneMenu
中的对象必须有适当的 equals()
方法 ,而不仅仅是默认的 Object#equals
他们是同一个对象。这解释了为什么初始显示的值总是第一个:bean 值从未匹配任何可能的值,因此 SelectOneMenu
组件只显示第一个。
所以错误不在 JSF 或支持 bean 代码中,而在显示的域对象的 (MediaType) 代码中。在那里添加 equals() 方法解决了问题。