h:selectManyCheckbox和omnifaces.SelectItemsConverter不会预选项目 [英] h:selectManyCheckbox with omnifaces.SelectItemsConverter does not preselect the items

查看:120
本文介绍了h:selectManyCheckbox和omnifaces.SelectItemsConverter不会预选项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 JSF 2.0, PrimeFaces OmniFaces .

I'm using JSF 2.0, PrimeFaces and OmniFaces.

我有2个使用<h:selectManyCheckbox>的对话框.第一个对话框创建一个新的Course:

I have 2 dialogs with <h:selectManyCheckbox>. The first dialog creates a new Course:

Disciplina表示为:

<h:selectManyCheckbox id="disciplinas" 
    value="#{cursoMBean.listaDisciplinasDoCurso}"
    converter="omnifaces.SelectItemsConverter">
    <f:selectItems value="#{cursoMBean.listaTodasDisciplinas}"
        var="disciplina" itemValue="#{disciplina}"
        itemLabel="#{disciplina.nome}" />
</h:selectManyCheckbox>

这很好.当我选择一些学科并提交表格时,带有所选Discipline的新Course将正确插入数据库中.

This works fine. When I select some disciplines and submit the form, then the new Course with the selected Disciplines is properly inserted in the DB.

但是,当我尝试从数据库中检索现有的Course时,未预先选择保存的Discipline.

However, when I try to retrieve an existing Course from the DB, the saved Disciplines are not preselected.

代码相同:

<h:selectManyCheckbox id="disciplinas" 
    value="#{cursoMBean.listaDisciplinasDoCurso}"
    converter="omnifaces.SelectItemsConverter">
    <f:selectItems value="#{cursoMBean.listaTodasDisciplinas}"
        var="disciplina" itemValue="#{disciplina}"
        itemLabel="#{disciplina.nome}" />
</h:selectManyCheckbox>

这是支持bean:

private ArrayList<Disciplina> listaTodasDisciplinas;
private ArrayList<Disciplina> listaDisciplinasDoCurso;

public CursoMBean() {
    if (listaTodasDisciplinas == null) {
        listaTodasDisciplinas = controleDisciplina.consulta();
    }

    if (listaDisciplinasDoCurso == null) {
        listaDisciplinasDoCurso = new ArrayList<Disciplina>();
    }
}

// When user selects one Course to edit, this method is called:
public void setSelecionado(Curso selecionado) {
    this.selecionado = selecionado;

    if (selecionado != null) {
        listaTodasDisciplinas = controleDisciplina.consulta();
        listaDisciplinasDoCurso = controleCurso.listaDisciplinasAssociadas(selecionado);
    }
}

这是Disciplina实体:

public class Disciplina {

    private int id;
    private String nome;

    public Disciplina() {
    }

    public Disciplina(int id, String nome) {
        this.id = id;
        this.nome = nome;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        if (!(nome.isEmpty() || nome == " " || nome == "  ")){
            this.nome = nome;
        }
    }

}

这是怎么引起的,我该如何解决?

How is this caused and how can I solve it?

推荐答案

默认情况下,SelectItemsConverter依赖于实体的toString()来匹配所选项目.但是,您的实体没有实现toString(),因此依赖默认的fqn@hashcode结果,当创建两个物理上不同的Disciplina实例时,即使它们具有相同的值,该结果也不相同.

By default, the SelectItemsConverter relies on toString() of the entity to match the selected items. Your entity however doesn't have a toString() implemented and is thus relying on default fqn@hashcode result which is not the same when two physically different Disciplina instances are created even though they have the same value.

基本上,您有2个选项,也显示在SelectItemsConverter 展示柜 javadoc :

You've basically 2 options, also hinted in SelectItemsConverter showcase and javadoc:

  1. 实施toString方法,该方法唯一地标识实体,并且可以作为标识符使用.例如,

  1. Implement a toString method that uniquely identifies the entity and which makes sense as an identifier. For example,

@Override
public String toString() {
    return String.format("%s[id=%d]", getClass().getSimpleName(), getId());
}

(请注意,此toString()的设计目的是,您可以轻松地将其保留在所有实体的抽象基类中,从而无需在所有实体上都粘贴相同的内容)

(note that this toString() is designed such that you can easily keep it in an abstract base class of all your entities, so that you don't need to copypaste the same over all your entities)

或者,如果出于某种原因(例如,依赖生成的类,这些类以后不能修改)(都不生成模板),则不能实现这样的toString(),则可以如下扩展转换器:

Or, if implementing such a toString() is not an option for some reason (e.g. relying on generated classes which can't be modified afterwards (neither the generator template)), then extend the converter as follows:

@FacesConverter("disciplinaSelectItemsConverter")
public class DisciplinaSelectItemsConverter extends SelectItemsConverter {

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        Integer id = (value instanceof Disciplina) ? ((Disciplina) value).getId() : null;
        return (id != null) ? String.valueOf(id) : null;
    }

}

(注意:您实际上应该使用Integer而不是int作为ID,int不能为null,这是表示一个全新且持久的实体的正确方法)

(note: you should really be using Integer instead of int as ID, the int cannot be null which is the correct way to represent a brand new and unpersisted entity)

并按如下所述使用它

<h:selectManyCheckbox ... converter="disciplinaSelectItemsConverter">

这篇关于h:selectManyCheckbox和omnifaces.SelectItemsConverter不会预选项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆