我的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();
}
在此转换器上,Argument'String value'给出itemLabel 我为什么会这样? 我在这个字符串上使用itemValue
答案 0 :(得分:19)
我不确定为什么你得到了项目标签而不是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>
和你的转换器如下(省略了零空值检查):
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}
更改为指向Long
属性学生证。
答案 1 :(得分:1)
您必须在f:selecitems
h:selectOneMenu
属性中使用选择项列表
您的页面将是这样的;
<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选择项。
private List<SelectItem> studentSelectItemList;
//fill studentSelectItemList at the appropriate place
studentSelectItemList.add(new SelectItem(studentId,studentName));
完成这些设置后,您应将学生ID作为选择值。
答案 2 :(得分:0)
今天我遇到了同样的问题。
这是由错误的渲染引起的:
<select ...>
<option>None</option>
<option value="1">First</option>
<option value="2">Second</option>
</select>
省略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
救援:)
答案 3 :(得分:0)
BalusC(再次)为我钉了这个。 我遇到了同样的问题,正如BalusC先前指出的那样,我的转换器的getAsString()方法返回了我的对象&#34; firstname&#34;属性。
@覆盖 public String getAsString(FacesContext context,UIComponent component,Object value){
if (value == null || value.equals("")) {
return "";
}
else {
return String.valueOf(((Employee) value).getfirstname());
}
}
我改变了这个以返回id,它开始按预期工作。
@覆盖 public String getAsString(FacesContext context,UIComponent component,Object value){
if (value == null || value.equals("")) {
return "";
}
else {
return String.valueOf(((Employee) value).getId());
}
}
BalusC您非常感谢您解释该理论的努力。你是天才!