在向下钻取SelectOneMenus(Parent-Child)中显示值

时间:2011-10-10 15:01:50

标签: java jsf java-ee jsf-2

当我填充两个selectOneMenu的深入选择时,我有一个恼人的问题。第一个菜单是扇区,它控制另一个 Categorty 。我根据扇区加载了类别的选择,所有这一切都正常。

但是当我编辑一个附有Category(有一个)Sector的业务对象时。首次加载 edit.xhtml 页面时,不会显示类别。我知道SessionScoped支持bean中的值是正确的。如果我选择另一个扇区类别,然后返回到初始扇区,那么类别得到正确设置,它就会被保留在第一位。

POJO类(Sector-Category)具有hashCode()equals(Object object)函数。

我为POJO对象生成了CRUD生成的JSF转换器,但我不认为这会导致问题。我认为第二个selectOneMenu由于某种原因没有显示其值。如果我将父(Sector)转换为其他内容并返回初始状态,则会显示来自manged bean的正确值。

我可以让类别selectOneMenu组件显示托管bean中的值吗?

问候克里斯

面对错误消息

FacesMessage(s) have been enqueued, but may not have been displayed.
sourceId=null[severity=(ERROR 2), summary=(No activity selected), detail=(No activity selected)]

Edit.xhtml

... 
<h:outputLabel value="Sector:" />                    
<h:selectOneMenu id="sectorSelector" value="#{activityController.selectedSector}" title="#{bundle.CreateSectorLabel_sectorName}" required="false" requiredMessage="#{bundle.CreateSectorRequiredMessage_sectorName}"
        valueChangeListener="#{activityController.changeSectorMenu}"
            disabled="#{activityController.activityStatusOngoing or activityController.activityStatusComplete}">
    <f:ajax event="change" execute="@this" render="categoryMenu"/>
            <f:selectItems value="#{sectorController.itemsAvailableSelectOne}"/>
</h:selectOneMenu>

<h:outputLabel value="Category:" />
    <h:selectOneMenu id="categoryMenu" value="#{activityController.selectedCategory}" title="#{bundle.CreateSectorLabel_sectorName}" 
        required="true" requiredMessage="#{bundle.CreateCategoryRequiredMessage_sector}"
            disabled="#{activityController.activityStatusOngoing}" rendered="true"> 
    <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;
    ...

2 个答案:

答案 0 :(得分:0)

选项(不像我最近做的那样困难)是包括Seam Faces和Persistence模块。 Seam Faces模块启用ViewScope而不使用@ManagedBean注释。

但SeamFaces强迫我们(这是合理的)使用CDI注释(@Named而不是@ManagedBean等)。

<强> Please refer this post 即可。 (您可以使用@EJB并注入任何使用@Named注释的bean)

答案 1 :(得分:0)

我最初想的不是转换器。这是两个selectOneMenu的渲染。这是我对xhml文件所做的更改。谢谢你的时间和精力,问候克里斯。

Edit.xhml

<h:outputLabel value="Sector:" />                    
<h:selectOneMenu id="sectorSelector" value="#{activityController.selectedSector}" title="#{bundle.CreateSectorLabel_sectorName}" required="false" requiredMessage="#{bundle.CreateSectorRequiredMessage_sectorName}"
        valueChangeListener="#{activityController.changeSectorMenu}" immediate="true"
            disabled="#{activityController.activityStatusOngoing or activityController.activityStatusComplete}">
    <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.selectedCategory}" title="#{bundle.CreateSectorLabel_sectorName}" 
        binding="#{activityController.categoryMenu}"
            required="true" requiredMessage="#{bundle.CreateCategoryRequiredMessage_sector}"                                     
            disabled="#{activityController.activityStatusOngoing}">
            <f:selectItems value="#{activityController.categorySelection}"/>
</h:selectOneMenu>