4

我正在使用 JSF 2.0 和 Primefaces 3.4.2

我在 JSF 页面中有以下内容

<p:selectOneMenu value="#{mb.employee}">
    <f:selectItems value="#{mb.employeeList}" var="emp"
    itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeCode}"/>
    <p:ajax listener="#{mb.changeMethod}" />
</p:selectOneMenu>

问题是当我在 selectOneMenu 中选择一个值时,我在 ManagedBean 的 changeMethod 中得到空值,为此System.out.println("val "+employee.getEmployeeName());

这可能是什么原因?我该如何解决这个问题?任何 hep 都是非常可观的。

ManagedBean代码

@Named("mb")
@ViewAccessScoped
public class MyBean implements Serializable {

private Employee employee;
private List<Employee> employeeList;

@Inject
EmployeeService employeeService;

@PostConstruct
public void loadEmployees() {
employeeList = employeeService.getEmployees();
}


public void changeMethod() {
System.out.println("val  "+employee.getEmployeeName());
}


/* getters and setters for employee and employeeList */
.... methods
/* */

您没有在<p:ajax>组件上指定要处理的表单元素,因此 ajax 请求可能会提交可能与其他字段验证冲突的多个值。请记住,如果一个值被提交并且它没有通过验证,那么没有一个请求值被设置到模型中。当您到达 Application(Event) 阶段时,模型值将不会反映任何提交的请求值。

试试这个:

<p:selectOneMenu value="#{mb.employee}">
    <f:selectItems value="#{mb.employeeList}" var="emp"
    itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeCode}"/>
    <p:ajax process="@this" partialSubmit="true" listener="#{mb.changeMethod}" />
</p:selectOneMenu>

在上面,您将仅提交要应用于模型的当前组件请求值。

编辑:

实际上,它可能不是一个验证问题,因为没有在 ajax 事件上提交请求值。

根据 Primefaces 手册:

处理 null 字符串组件以在部分请求中处理。

更新空字符串组件以使用 ajax 进行更新。

第二列是默认值。在标准<f:ajax>中,execute属性默认为,@this但是对于<p:ajax>. 如果要提交当前组件,则必须在process属性中指定。

4

2 回答 2

9

您没有在<p:ajax>组件上指定要处理的表单元素,因此 ajax 请求可能会提交可能与其他字段验证冲突的多个值。请记住,如果一个值被提交并且它没有通过验证,那么没有一个请求值被设置到模型中。当您到达 Application(Event) 阶段时,模型值将不会反映任何提交的请求值。

尝试这个:

<p:selectOneMenu value="#{mb.employee}">
    <f:selectItems value="#{mb.employeeList}" var="emp"
    itemLabel="#{emp.employeeName}" itemValue="#{emp.employeeCode}"/>
    <p:ajax process="@this" partialSubmit="true" listener="#{mb.changeMethod}" />
</p:selectOneMenu>

在上面,您将仅提交要应用于模型的当前组件请求值。

编辑:

实际上,它可能不是一个验证问题,因为没有在 ajax 事件上提交请求值。

根据 Primefaces 手册:

处理 null 字符串组件以在部分请求中处理。

更新空字符串组件以使用 ajax 进行更新。

第二列是默认值。在标准<f:ajax>中,execute属性默认为,@this但是对于<p:ajax>. 如果要提交当前组件,则必须在process属性中指定。

于 2013-02-20T19:17:35.030 回答
2

您需要将转换器添加到p:selectOneMenu以让它知道您正在处理员工对象。创建转换器类并将其与转换器属性一起使用。这是示例转换器。

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;

@FacesConverter("employeeConverter")
@Configurable
public class EmployeeConverter implements Converter {

    @Autowired
    EmployeeService employeeService;

    public Object getAsObject(FacesContext context, UIComponent component,
            String value) {
        if (value == null || value.length() == 0) {
            return null;
        }
        Long id = Long.parseLong(value);
        return employeeService.findUser(id);
    }

    public String getAsString(FacesContext context, UIComponent component,
            Object value) {
        return value instanceof Employee ? ((Employee) value).getId().toString() : "";
    }
}
于 2013-02-21T15:05:17.343 回答