Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/jsf/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF2:在呈现属性中使用枚举_Jsf_Enums_Jsf 2_El - Fatal编程技术网

JSF2:在呈现属性中使用枚举

JSF2:在呈现属性中使用枚举,jsf,enums,jsf-2,el,Jsf,Enums,Jsf 2,El,是否有任何方法以声明方式检查枚举是否具有指定的值。例如: <h:graphicImage name="error.png" library="images" rendered="#{viewController.current.status == Status.ERROR}" /> 是否有一种更短/更好的方法来执行此操作?不可能在EL范围内导入枚举。但是,您可以像字符串一样处理和比较它们,即枚举常量值必须如下所示引用 <h:graphicImage name="erro

是否有任何方法以声明方式检查枚举是否具有指定的值。例如:

<h:graphicImage name="error.png" library="images" 
  rendered="#{viewController.current.status == Status.ERROR}" />
是否有一种更短/更好的方法来执行此操作?

不可能在EL范围内导入枚举。但是,您可以像字符串一样处理和比较它们,即枚举常量值必须如下所示引用

<h:graphicImage name="error.png" library="images" 
  rendered="#{viewController.current.status eq 'ERROR'}" />

我知道这个问题现在有点老了,但我遇到了同样的问题,找到了另一个解决方案,我想与大家分享:

创建自定义EL解析器并在jsf中将枚举和java常量用作对象EL:

<h:graphicImage name="error.png" library="images"  
      rendered="#{viewController.current.status == Status.ERROR}" />
希望这减少但工作的代码可以帮助任何人


更新

我看到这一好处:

  • 如果在jsf中使用字符串(viewController.current.status='ERROR\u abcdefg'),则可能会拼写错误,并且无法很快识别该值。 在我的解决方案中,加载jsf文件时会出现错误,因为无法解析枚举

  • 您可以在源代码中看到“ERROR”是枚举“STATUS”的值

  • 比较el中的两个值时,也会比较枚举的类。 例如PersonState.ACTIV与AccounState.ACTIV不同

  • 当我必须将枚举值从PersonState.ACTIV更改为PersonState.ACTIVATED时,我可以在源代码中搜索字符串“PersonState.ACTIV”。搜索“ACTIV”将有更多的匹配项


  • 我解决了一个类似的问题,方法是
    静态地
    转储映射中的所有枚举键(在渲染的UI组件中使用),然后使用静态
    getByKey
    方法将UI中的值转换为setter中的实际本机枚举,如果提供的值无效,则引发异常:

    public enum ReportType {
    
        FILING("F", "Filings"),
        RESOLUTION("R", "Resolutions"),
        BASIS("B", "Bases"),
        STAFF("T", "Staff Counts"),
        COUNTS("I", "Counts");
    
        private String key;
        private String label;
    
        private static Map<String, ReportType> keyMap = new HashMap<String, ReportType>();  
    
        static {
            for(ReportType type : ReportType.values()) {
                keyMap.put(type.getKey(), type);
            }
        }
    
        private ReportType(String _key, String _label) {
            this.key = _key;
            this.label = _label;
    
        }
    
        public String getKey() {
            return this.key;
        }
    
        public String getLabel() {
            return this.label;
        }
    
        public static List<ReportType> getValueList() {
            return Arrays.asList(ReportType.values());
        }
    
        public static ReportType getByKey(String _key) {
            ReportType result = keyMap.get(_key);
    
            if(result == null) {
                throw new IllegalArgumentException("Invalid report type key: " + _key);
            }
    
            return result;
        }
    }
    
    最后,托管bean中的[g|s]字母如下所示:

    public String getReportType() {
        return this.crtRptType.getKey();
    }
    
    public void setReportType(String _val) {
        this.crtRptType = ReportType.getByKey(_val);
    }
    

    我认为可以通过以下方式实现:

    例如,在bean中创建一个返回枚举列表的方法

    public Status[] getStatuses() {
      Status.values();
    }
    
    然后可以像这样在EL中使用枚举

    <h:graphicImage name="error.png" library="images" 
      rendered="#{viewController.current.status == someBean.statuses[0]}" />
    

    这仍然不是动态解决方案,但它比EL中的硬编码要好。当您对状态使用本地化(枚举值取决于区域设置/转换)时,可能特别有用

    这种方法到底给你带来了什么好处?在Java中,使用直接枚举引用的主要优点是编译时强制执行有效值,但这种优点在EL中不存在,也不存在于此解析器中。这甚至比在托管bean中创建方法更繁琐!不过,很高兴知道这是可以做到的。字符串比较的计算方法类似于调用equals()方法,还是类似于引用比较?
    baseCache.put(CLASS_WITH_CONSTANTS.getSimpleName(), clazz);
    for (Field field : CLASS_WITH_CONSTANTS.getDeclaredFields()) {
        try {
            propertCache.put(CLASS_WITH_CONSTANTS.getSimpleName() + "." 
                      + field.getName(), field.get(null));
        } catch (Exception e) { }
    }
    
    public enum ReportType {
    
        FILING("F", "Filings"),
        RESOLUTION("R", "Resolutions"),
        BASIS("B", "Bases"),
        STAFF("T", "Staff Counts"),
        COUNTS("I", "Counts");
    
        private String key;
        private String label;
    
        private static Map<String, ReportType> keyMap = new HashMap<String, ReportType>();  
    
        static {
            for(ReportType type : ReportType.values()) {
                keyMap.put(type.getKey(), type);
            }
        }
    
        private ReportType(String _key, String _label) {
            this.key = _key;
            this.label = _label;
    
        }
    
        public String getKey() {
            return this.key;
        }
    
        public String getLabel() {
            return this.label;
        }
    
        public static List<ReportType> getValueList() {
            return Arrays.asList(ReportType.values());
        }
    
        public static ReportType getByKey(String _key) {
            ReportType result = keyMap.get(_key);
    
            if(result == null) {
                throw new IllegalArgumentException("Invalid report type key: " + _key);
            }
    
            return result;
        }
    }
    
    <f:selectItems var="rptTypeItem" value="#{reportController.allReportTypes}" 
        itemLabel="#{rptTypeItem.label}" itemValue="#{rptTypeItem.key}"/>
    
    public List<ReportType> getAllReportTypes() {
        return ReportType.getValueList();
    }
    
    public String getReportType() {
        return this.crtRptType.getKey();
    }
    
    public void setReportType(String _val) {
        this.crtRptType = ReportType.getByKey(_val);
    }
    
    public Status[] getStatuses() {
      Status.values();
    }
    
    <h:graphicImage name="error.png" library="images" 
      rendered="#{viewController.current.status == someBean.statuses[0]}" />
    
    public Status[] getStatuses() {
      Status myStatuses = new Status [2]; // or whatever number of statuses you are going to use in UI
      myStatuses [0] = Status.ERROR;
      myStatuses [1] = Status.RUNNING;
      return myStatuses;
    }