ValueChangeEvent尽管值未发生变化

时间:2016-07-19 18:17:26

标签: jsf primefaces

我不明白为什么这个问题是重复的。如果我调试代码然后 - 当单击按钮时 - 没有检测到projectSelected的新值。即使hashCode也是一样的。 ProjectEntity的equals方法只包含相同的id,因为它来自数据库并且不会在任何地方更改。选择中不存在空值。

然而,有很多代码可以重现这个问题。我删除了不必要的代码,问题仍然存在。

原始问题:如果点击了提交按钮,则在以下表单中包含3个<p:selectOneMenu>字段,但valueChangeEvent字段会触发projectSelector没有改变。这是为什么?就像那样,按钮背后的实际动作永远不会被调用。我希望只有在项目发生变化时才会触发valueChangeEvent

更新 :尝试查找原因我用String替换了ProjectEntity,然后就可以了。所以我认为它必须是ProjectEntity的equals方法,但只比较id。我进一步调试并发现所选值与ProjectEntity进行比较,所有字段都设置为null,这给出了false,因此给出了valueChangeEvent。所以问题是为什么ProjectEntity的所有字段都设置为null?我调试了UIInput.compareValues,其中“null”-ProjectEntity是以前的值。这是由UIOuput.getLocalValue返回的。它来自哪里?

Update2 :即使使用selectOneMenu shows after submit always the last item in the list as selected item中的equals和hashCode,行为也不会改变。我创建了一个ear file,很容易被部署到例如一只野蝇,我会感激任何帮助,因为我被困在这个问题上。

<h:form>
    <p:outputLabel value="#{msgs.timeProject}"/>
    <p:selectOneMenu value="#{timeBean.model.projectSelected}"
                     converter="projectConverter"
                     onchange="submit()"
                     valueChangeListener="#{timeBean.projectChanged}"
                     immediate="true"
                     required="true">
        <f:selectItems value="#{timeBean.model.allProjects}"
                       var="singleProject"
                       itemValue="#{singleProject}"
                       itemLabel="#{singleProject.name}"/>
    </p:selectOneMenu>
    <p:commandButton value="#{msgs.send}"
                     action="#{timeBean.myAction}"
                     ajax="false"/>
    <p:outputLabel value="#{timeBean.model.resultValue}" 
                   rendered="#{not empty timeBean.model.resultValue}"/>
</h:form>

转换器

@FacesConverter(value = "projectConverter")
public class ProjectConverter implements Converter {

    @Inject
    private ProjectService projectService;

    @Override
    public Object getAsObject(final FacesContext facesContext, final UIComponent uiComponent, final String projectName) {
        if (StringUtils.isEmpty(projectName)) {
            return null;
        }
        final List<ProjectEntity> projects = projectService.findAll();
        for (ProjectEntity project : projects) {
            if (StringUtils.equals(projectName, project.getName())) {
                return project;
            }
        }
        return null;
    }

    @Override
    public String getAsString(final FacesContext facesContext, final UIComponent uiComponent, final Object value) {
        if (value == null) {
            return null;
        }
        if (value instanceof ProjectEntity) {
            return ((ProjectEntity) value).getName();
        }
        return "???projectName???";
    }
}

ProjectEntity的equals-method

@Override
public boolean equals(final Object o) {
    if (this == o)
        return true;
    if (o == null || getClass() != o.getClass())
        return false;

    final ProjectEntity that = (ProjectEntity) o;

    return id != null ? id.equals(that.id) : that.id == null;
}

timeBean中的更改侦听器

public void projectChanged(final ValueChangeEvent event) {
    final ProjectEntity projectSelected = (ProjectEntity) event.getNewValue();
    model.setProjectSelected(projectSelected);
    final FacesContext context = FacesContext.getCurrentInstance();
    context.renderResponse();
}

TimeModel

public class TimeModel {
    private ProjectEntity projectSelected;
    private List<ProjectEntity> allProjects;
    private String resultValue;
    ... getters and setters ...

1 个答案:

答案 0 :(得分:0)

我猜,问题存在于ProjectConverter类中,导致分配有效的projectService实例可能会遇到麻烦。也许您删除了注入并尝试通过显式cdi-finders在getAsObject,getAsString方法中以编程方式计算值。

当我注入ServletFilter时,我记得在类似的情况下运行。