在GSP页面上显示枚举值,并将它们绑定到数据库中。

8

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

所以我的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

有什么想法吗?
3个回答

9

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

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
<%@ 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()]

或类似于您控制器返回的内容。

<%@ page import="ENUM.MyEnum" contentType="text/html;charset=UTF-8" %> - Nikhil Sharma
首先,你的语法是错误的,UPPERCASE的部分是一个变量名,而不是参数。所以你可以删掉名字这一部分。其次,导入类时不需要添加contentType属性。第三,当我使用你的类进行测试时,它在这里工作了,我将在gist中更新答案。 - Oliver Tynes
你需要导入枚举类,而不是枚举常量 <%@ page import="fully.qualified.path.MyEnum" %> - Dónal
@Oliver,“getAllEnumList()”方法是多余的,每个枚举已经提供了一个执行相同操作的“values()”方法。 - Dónal
是的,我知道,我只是想展示一下我对他的类做了哪些修改,但提到这点也很好。 - Oliver Tynes

2
你可以使用自定义标签库来避免在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"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接