【问题标题】:Show enum values on GSP page and then bind them in the database在 GSP 页面上显示枚举值,然后将它们绑定到数据库中
【发布时间】:2011-07-29 11:58:53
【问题描述】:

我有一个用例,我需要首先在 GSP 页面上将 enum 的值显示为下拉列表,让用户选择其中一个值,然后最后将数据绑定到域。

所以我在 GSP 上的代码看起来像我的枚举是 MyEnum

<g:select from="${MyEnum.getAllEnumList()}" optionValue="name" name="duration"/>

我的枚举是

public enum MyEnum {

    MIN15('15 Minutes'),
    MIN30('30 Minutes'),
    HOUR1('1 Hour'),
    HOUR2('2 Hours'),
    HOUR5('5 Hours'),
    HOUR8('8 Hours'),
    HALFDAY('half day'),
    FULLDAY('full day')

    private final String name
    private final String displayName

    public static final List<MyEnum> getAllEnumList() {
        [MIN15,MIN30,HOUR1,HOUR2,HOUR5,HOUR8,HALFDAY,FULLDAY]
    }

    public String toString() {
        return displayName
    }

    MyEnum(String name,String displayName) {
        this.name = name
        this.displayName = displayName;
    }

}

当我点击页面时,它显示如下错误:

Error processing GroovyPageView: Error executing tag <g:form>: Error evaluating expression [MyEnum.getAllEnumList()] on line [37]: java.lang.NoClassDefFoundError: Could not initialize class ENUM.MyEnum at D:/myspace/projects/IcepushpluginSampleApp/grails-app/views/util/test.gsp:46

有什么想法吗????

【问题讨论】:

    标签: grails enums gsp


    【解决方案1】:

    这就是我过去的做法。这样你就有了 i18n 支持。

    gsp

    <g:select name="duration" from="${MyEnum.values()}" valueMessagePrefix="ENUM.MyEnum" />
    

    messages.properties

    ENUM.MyEnum.MIN15=15 Minutes
    ENUM.MyEnum.MIN30=30 Minutes
    ENUM.MyEnum.HOUR1=1 Hour
    ENUM.MyEnum.HOUR2=2 Hours
    ENUM.MyEnum.HOUR5=5 Hours
    ENUM.MyEnum.HOUR8=8 Hours
    ENUM.MyEnum.HALFDAY=half day
    ENUM.MyEnum.FULLDAY=full day
    

    【讨论】:

      【解决方案2】:

      如果您使用custom tag library,则可以避免在 GSP 中导入(这有点难看)。如果您希望选项键与其值不同,您还需要向您的enum 添加另一种方法 (getKey())。

      MyEnum.groovy

      enum MyEnum {
          MIN15('15 Minutes'),
          MIN30('30 Minutes'),
          HOUR1('1 Hour'),
          HOUR2('2 Hours'),
          HOUR5('5 Hours'),
          HOUR8('8 Hours'),
          HALFDAY('half day'),
          FULLDAY('full day')
      
          final String displayName
      
          private MyEnum(String displayName) {
              this.displayName = displayName
          }
      
          String getKey() {
              name()
          }
      
          String toString() {
              displayName
          }
      }
      

      MyEnumTagLib.groovy

      // add import if MyEnum is in a different package
      
      class MyEnumTagLib {
          static namespace = 'my'
      
          def enumSelect = { attrs ->
              attrs.from = MyEnum.values()
              attrs.optionKey = 'key'
              out << g.select(attrs)
          }
      }
      

      gsp

      <my:enumSelect name="duration"/>
      

      【讨论】:

        【解决方案3】:
        <%@ page import="fully.qualified.path.MyEnum" %>
        

        在您的 GSP 顶部尝试此操作(当然,要根据您的包调整完全合格的路径)。

        编辑(这应该可以工作(你的枚举语法也是错误的)):

        <%@ page import="ENUM.MyEnum" %>
        <html>
        <head>
        </head>
        <body>
        <g:select from="${MyEnum.getAllEnumList()}" optionValue="displayName" name="duration"/>
        </body>
        </html>
        

        然后是修改后的类:

        package ENUM
        
        public enum MyEnum {
        
            MIN15('15 Minutes'),
            MIN30('30 Minutes'),
            HOUR1('1 Hour'),
            HOUR2('2 Hours'),
            HOUR5('5 Hours'),
            HOUR8('8 Hours'),
            HALFDAY('half day'),
            FULLDAY('full day')
        
        
            private final String displayName
        
            public static final List<MyEnum> getAllEnumList() {
                [MIN15,MIN30,HOUR1,HOUR2,HOUR5,HOUR8,HALFDAY,FULLDAY]
            }
        
            public String toString() {
                return displayName
            }
        
            MyEnum(String displayName) {
        
                this.displayName = displayName;
            }
        }
        

        编辑2:

        避免整个事情的最简单方法(这里的第二个答案和我的解决方案)是简单地将值列表从控制器传递给 gsp。只需添加

        [duration:MyEnum.values()]
        

        或类似于您的控制器返回的东西。

        【讨论】:

        • 首先,你的语法是错误的,大写的东西是一个变量名,而不是一个参数。因此,您可以删除名称部分。其次,您不需要为导入类添加 contentType 属性。第三,当我对你的课程进行测试时,它会在这里工作,并会用要点更新答案。
        • 你需要导入枚举类,而不是枚举常量&lt;%@ page import="fully.qualified.path.MyEnum" %&gt;
        • @Oliver 的getAllEnumList() 方法是多余的,每个枚举都已经提供了一个做同样事情的values() 方法
        • 是的,我知道,我只是想向他展示我对他的课程做了哪些修改,不过还是要提一下。
        猜你喜欢
        • 2010-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-09
        • 2016-04-08
        • 2015-12-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多