【问题标题】:selectOneMenu do not render/display valueselectOneMenu 不渲染/显示值
【发布时间】:2011-10-18 10:29:19
【问题描述】:

早前就该主题发表过一篇文章 (Display values in drill-down SelectOneMenus)。我最初想到的问题与对象转换器无关。

我有两个 selectOneMenu 相互依赖,Sector -> Category。当我坚持持有一个部门和类别的后台业务对象时,一切都按预期工作。即使在当前用户会话终止并且用户再次登录并编辑之前保存的业务对象之后。

当实体管理器刷新对象并且用户想要从数据库中再次显示扇区、类别时,就会出现问题。扇区selectOneMenu 显示其值,但不显示类别selectOneMenu 值。尽管支持 bean 具有来自数据库的正确值。

是什么让selectOneMenu在从数据库而不是从内存中加载某些持久值/对象时不显示它们?

编辑.xhtml

<h:outputLabel value="Sector:" />
<h:selectOneMenu id="sectorSelector" value="#{activityController.selected.category.sector}" title="#{bundle.CreateSectorLabel_sectorName}" valueChangeListener="#{activityController.changeSectorMenu}" immediate="true">
            <a4j:ajax event="change" execute="@this categoryMenu" render="categoryMenu"/>
            <f:selectItems value="#{sectorController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>

<h:outputLabel value="Category:" />
    <h:selectOneMenu id="categoryMenu" value="#{activityController.selected.category}" title="#{bundle.CreateSectorLabel_sectorName}" 
        binding="#{activityController.categoryMenu}"
            required="true" requiredMessage="#{bundle.CreateCategoryRequiredMessage_sector}">                        
    <f:selectItems value="#{activityController.categorySelection}"/>
</h:selectOneMenu>

类别的控制器 bean

@ManagedBean(name = "categoryController")
@SessionScoped
public class CategoryController implements Serializable{

    ....

    @FacesConverter(forClass = Category.class)
    public static class CategoryControllerConverter implements Converter {

        @Override
        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            CategoryController controller = (CategoryController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "categoryController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Integer getKey(String value) {
            java.lang.Integer key;
            key = Integer.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Integer value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        @Override
        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof Category) {
                Category o = (Category) object;
                return getStringKey(o.getIdCategory());
            }
            else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + CategoryController.class.getName());
            }
        }
    }

POJO 对象的一部分

...
public class Category implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "idCategory")
    private Integer idCategory;
    ...

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Category)) {
            return false;
        }
        Category other = (Category) object;
        if ((this.idCategory == null && other.idCategory != null) || (this.idCategory != null && !this.idCategory.equals(other.idCategory))) {
            return false;
        }
        return true;
}

创建 SelectItem[] 数组的函数

public static SelectItem[] getSelectItems(List<?> entities, boolean selectOne) {

        int size = entities.size();
        SelectItem[] items;
        int i = 0;
        if (selectOne) {
            items = new SelectItem[size + 1];
            items[0] = new SelectItem("", ResourceBundle.getBundle("/resources/Bundle").getString("Select_item"));
            i++;
        } else {
            items = new SelectItem[size];
        }

        for (Object x : entities) {
            items[i++] = new SelectItem(x, x.toString());
        }
        return items;
    }

【问题讨论】:

  • 这表示您的Categoryequals() 丢失或损坏。显示它。
  • Category equals() 之类的接缝永远不会被调用。但该部门的人确实如此。此外,不会在 Category bean 类上调用 getAsString() 方法。为什么当它们看起来相同时不会为一个类调用equals,而是为另一个类调用equals?
  • 这反过来表明&lt;f:selectItems&gt; 不包含Category 对象作为值。也许您将List&lt;String&gt; 而不是List&lt;Category&gt; 传递给您的getSelectItems()

标签: jsf jpa jsf-2 jpa-2.0


【解决方案1】:

问题是当用户编辑业务对象时我没有正确的SelectItems 集合。另外,我添加了&lt;f:converter&gt; 以显式调用转换器,我在getAsString()(其他部分)中做了一些更改。

感谢您抽出宝贵时间,希望这篇文章对其他人有用。

SelectMenuOne

public String prepareEditOrganisationActivity() {
        current = (Activity) organisationActivityItems.getRowData();
        Sector sector = current.getCategory().getSector();
        CategoryController categoryBean = JsfUtil.findBean("categoryController", CategoryController.class);
        categorySelection = categoryBean.categoryItemsBySector(sector);

        return "EditActivity";
}

CategoryControllerConverter

...    
    @Override
    public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
        if (object == null) {
            return null;
        }
        if (object instanceof Category) {
            Category o = (Category) object;
            return getStringKey(o.getIdCategory());
        }
        else {
            Category tmp = new Category();
            return getStringKey(tmp.getIdCategory());                
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 2017-02-22
    • 2011-12-09
    • 2012-01-06
    相关资源
    最近更新 更多