我的JSF页面
<h:form>
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<p:ajax event="change" process="studlist" update="studdep" ></p:ajax>
<f:selectItems value="#{studBean.student}" var="s"
itemValue="#{s.studid}" itemLabel="#{s.name}"/>
<f:converter converterId="studentconverter"/>
</h:selectOneMenu>
</h:form>
转换器类(StudentConverter)
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Student studConvert= new Student();
List<Student> students=new ArrayList<Student>();
students=(ArrayList<Student>)((UISelectItems
component.getChildren().get(0)).getValue();
}
在这个转换器上参数'String value'给出了itemLabel为什么会这样?
我不知道为什么你得到了项目标签而不是getAsObject()
内的项目值。也许你的getAsString()
做错了,它根据学生ID返回学生名。
无论如何,我可以看出你的itemValue
肯定是不对的。
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<f:selectItems value="#{studBean.student}" var="s"
itemValue="#{s.studid}" itemLabel="#{s.name}" />
<f:converter converterId="studentconverter" />
</h:selectOneMenu>
转换器旨在用于在复杂的Java对象和String表示形式之间进行转换,以便它可以作为HTTP请求参数传递。但是,您指定的是学生ID作为项值,而不是整个学生对象。您需要指定整个学生对象。您还应该确保#{studBean.selectedStudent}
引用Student
属性,而不是代表学生ID的Long
属性。
当你修复itemValue
如下:
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<f:selectItems value="#{studBean.student}" var="s"
itemValue="#{s}" itemLabel="#{s.name}" />
<f:converter converterId="studentconverter" />
</h:selectOneMenu>
和您的转换器如下所示(省略了琐碎的null检查):
public String getAsString(FacesContext context, UIComponent component, Object value) {
// This method is called when item value is to be converted to HTTP request parameter.
// Normal practice is to return an unique identifier here, such as student ID.
Student student = (Student) value;
Long id = student.getStudid();
return String.valueOf(id);
}
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// This method is called when HTTP request parameter is to be converted to item value.
// You need to convert the student ID back to Student.
Long id = Long.valueOf(value);
Student student = someStudentService.find(id);
return student;
}
那么它应该可以工作。
或者,您可以保留您最初拥有的itemValue
并完全删除<f:converter>
,但随后您必须更改#{studBean.selectedStudent}
以指向代表学生ID的Long
属性。
你必须在h:selectOneMenu
的f:selecitems
属性中使用selectitem list
你的页面将是这样的;
<h:form>
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<p:ajax event="change" process="studlist" update="studdep" ></p:ajax>
<f:selectItems value="#{studBean.studentSelectItemList}" />
<f:converter converterId="studentconverter"/>
</h:selectOneMenu>
</h:form>
在后台bean端,您必须填充studentSelectItemList selectitem。
private List<SelectItem> studentSelectItemList;
//fill studentSelectItemList at the appropriate place
studentSelectItemList.add(new SelectItem(studentId,studentName));
在这些设置之后,您应该将学生id作为选择值。
今天我遇到了同样的问题
这是由错误的渲染引起的:
<select ...>
<option>None</option>
<option value="1">First</option>
<option value="2">Second</option>
</select>
为"None"选项省略value=""
将导致提交标签而不是空字符串。
然而,要解决这个问题并使渲染器为第一个选项编写value=""
,只需确保getAsString()
永远不会返回null,而是返回""
(空字符串)。
@BalusC
<h:form id="form">
...
<p:selectOneMenu id="targetStep" value="#{action.targetStep}" required="true">
<o:converter converterId="omnifaces.ListIndexConverter" list="#{entity.stepList}" />
<f:selectItems var="step" value="#{entity.stepList}" itemLabel="#{step.name}"
itemValue="#{step}" />
</p:selectOneMenu>
<p:commandButton process="@this" update="@widgetVar(stepDialog)"
oncomplete="PF('stepDialog').show()" icon="#{icons.addStep}"
value="#{bundle.addStep}">
<f:setPropertyActionListener target="#{viewScope.step}"
value="#{s:newInstance('it.shape.edea2.jpa.WorkflowStep')}" />
</p:commandButton>
<p:message for="targetStep" />
...
</h:form>
<p:dialog widgetVar="stepDialog" header="#{bundle.addStep}" modal="true" dynamic="true"
resizable="false">
<h:form>
<p:panelGrid columns="2" styleClass="app-full-width">
<h:outputLabel value="#{bundle.name}" />
<h:panelGroup>
<p:inputText id="name" value="#{step.name}" required="true" />
<p:message for="name" />
</h:panelGroup>
...
<f:facet name="footer">
<p:commandButton process="@form" update="@form :form"
oncomplete="hideDialog('stepDialog', args)" icon="#{icons.confirm}"
value="#{bundle.confirm}">
<p:collector value="#{step}" addTo="#{entity.stepList}" />
<f:setPropertyActionListener target="#{action.targetStep}"
value="#{step}" />
</p:commandButton>
</f:facet>
</p:panelGrid>
</h:form>
</p:dialog>
您的omnifaces.ListIndexConverter
来拯救:)
BalusC(再次)为我搞定了这个。我有同样的问题,正如BalusC早些时候指出的那样,我的转换器的getAsString()方法返回了我的对象的"firstname"属性。
@Overridepublic String getAsString(FacesContext context, uiccomponent component, Object value) {
if (value == null || value.equals("")) {
return "";
}
else {
return String.valueOf(((Employee) value).getfirstname());
}
}
我将其更改为返回id,并且它开始按预期工作。
@Overridepublic String getAsString(FacesContext context, uiccomponent component, Object value) {
if (value == null || value.equals("")) {
return "";
}
else {
return String.valueOf(((Employee) value).getId());
}
}
BalusC你解释这个理论的努力是非常赞赏的。你heavensent !