Почему выберите OneMenu Отправить ItemLabel конвертеру? - PullRequest
10 голосов
/ 11 августа 2011

моя страница 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 и почему это происходит ?? я использую itemValue в этой строке

Ответы [ 4 ]

19 голосов
/ 11 августа 2011

Я не уверен, почему вы получили метку элемента вместо значения элемента внутри getAsObject(). Возможно, ваш getAsString() делает это неправильно и возвращает имя студента на основе идентификатора студента.

В любом случае, я могу сказать, что ваш 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. Однако вы указываете идентификатор студента в качестве значения элемента вместо целого объекта студента. Вы должны указать весь объект студента вместо этого. Вы также должны убедиться, что #{studBean.selectedStudent} ссылается на свойство Student, а не на какое-либо свойство 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 голос
/ 11 августа 2011

Вы должны использовать список элементов select в атрибуте 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>

На стороне поддерживающего компонента вы должны заполнить элемент studentSelectItemList.

private List<SelectItem> studentSelectItemList;

//fill studentSelectItemList at the appropriate place
  studentSelectItemList.add(new SelectItem(studentId,studentName));

После этих настроек у вас должен быть идентификатор студента в качестве значения для выбора.

0 голосов
/ 12 мая 2015

BalusC (снова) прибил этот для меня.У меня была та же проблема, и как BalusC указывал ранее, метод getAsString () моего конвертера возвратил свойство моего объекта "firstname".

@ Переопределить общедоступную строку getAsString (контекст FacesContext, компонент UIComponent, значение объекта) {

    if (value == null || value.equals("")) {
        return "";
    }
    else {
        return String.valueOf(((Employee) value).getfirstname());
    }

}

Я изменил это, чтобы вернуть идентификатор, и он начал работать как ожидалось.

@ Переопределить общедоступную строку getAsString (контекст FacesContext, компонент UIComponent, значение объекта) {

    if (value == null || value.equals("")) {
        return "";
    }
    else {
        return String.valueOf(((Employee) value).getId());
    }

}

BalusC, ваши усилия объяснить теорию очень ценятся.Ты небесный!

0 голосов
/ 30 октября 2014

Сегодня у меня была такая же проблема.

Это вызвано неправильным отображением:

<select ...>
    <option>None</option>
    <option value="1">First</option>
    <option value="2">Second</option>
</select>

пропуск value="" для опции "Нет" приводит к отправке метки вместо пустой строки .

Однако, чтобы решить эту проблему и заставить средство рендеринга написать value="" для первого параметра, просто убедитесь, что getAsString() никогда не возвращает ноль , вместо него возвращается "" (пустая строка).


@ 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 на помощь:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...