selectOneMenu 不渲染/显示值

发布于 2024-12-10 15:45:49 字数 4575 浏览 0 评论 0原文

之前发表过一篇关于此主题的文章(在向下钻取 SelectOneMenus 中显示值< /a>)。正如我首先想到的那样,问题与对象转换器无关。

我有两个相互依赖的 selectOneMenu,Sector ->类别。当我保留包含部门和类别的后台业务对象时,一切都会按预期进行。即使当前用户会话终止并且用户再次登录并编辑先前保存的业务对象也是如此。

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

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

Edit.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;
    }

Made a post earlier about this topic (Display values in drill-down SelectOneMenus). The problem that have is not connected to the Object converters as I first thought.

I have two selectOneMenu depending on each other, Sector -> Category. When I persist the background business object that holds a Sector and Category, everything works as expected. Even after the current user session terminates and the user log on again and edit the previous saved business object.

The problem occur when and the entity manager flushes the objects and user wants to display the Sector, Category again from the database. The Sector selectOneMenu displays its value as it should, but the Category selectOneMenu value is not displayed. Although the backing bean has the correct value from the database.

What makes the selectOneMenuto not display certain persisted values/objects when they are loaded from database instead from in-memory?

Edit.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>

Controller bean for Category

@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());
            }
        }
    }

Part of POJO object

...
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;
}

Functon for creating the SelectItem[] array

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;
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

童话里做英雄 2024-12-17 15:45:49

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

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

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";
}

类别控制器转换器

...    
    @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());                
        }
    }

The problem was that I didn't have the right collection of SelectItems when the user edited a business object. Plus that I added the <f:converter> to explicitly invoke the converter, where I did some changes in the getAsString() (the else part).

Thank you for your time, and hope the post can be useful to someone else.

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());                
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文