Grails getProperties方法并不总是以正确的顺序返回属性

时间:2012-06-22 05:08:04

标签: json grails groovy flexigrid

我有一个看起来像这样的课程:

class Foo {
    name
    description

    static constraints = {
        name()
        description()
    }
}

我想在Flexigrid中添加班级的展示实例。当数据发送到flexigrid时,它需要采用JSON或XML格式......我选择了JSON。 Flexigrid希望它收到的JSON数组具有以下格式:

{
    "page": "1",
    "total": "1",
    "rows": [
        {
            "id": "1",
            "cell": [
                "1",
                "The name of Foo 1",
                "The description of Foo 1"
            ]
        },
        {
            "id": "2",
            "cell": [
                "2",
                "The name of Foo 2",
                "The description of Foo 2"
            ]
        }
    ]
}

为了使我的Foo个对象成为这种格式,我会做类似的事情:

def foos = Foo.getAll( 1, 2 )

def results = [:]
results[ "page" ] = params.page
results[ "total" ] = foos.size()
results[ "rows" ] = []

for( foo in foos ) {
    def cell = []
    cell.add( foo.id )

    foo.getProperties().each() { key, value -> // Sometimes get foo.getProperties().each() returns foo.description then foo.name instead of foo.name then foo.description as desired.
        cell.add( value.toString() )
    }

    results[ "rows" ].add( [ "id": foo.id, "cell": cell ] )
}

render results as JSON

问题在于,每隔一段时间foo.getProperties().each()会返回foo.description,然后foo.name会导致foo.description返回我的flexigrid的名称列,foo.name放入我的flexigrid的描述列中的特定行。

我尝试在Foo域类中指定约束,以便getProperties以正确的顺序返回,但它不起作用。 如何确保getProperties以可预测的顺序返回属性?

这是我修复此问题的方法:

def items = Foo.getAll()

for( item in items ) {
    def cell = []
    cell.add( item.id )
    Foo.constraints.each() { key, value ->
        def itemValue = item.getProperty( key )
        if( !( itemValue instanceof Collection ) ) {
            cell.add( itemValue.toString() )
        }
    }
}

因此Foo.constraints获取约束映射,其中每个约束都是Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry的实例。经过测试,我发现这个地图总是按照我输入的顺序返回我的Foo静态约束(也由Ian确认)。现在,只有itemFoo.constraints的属性才会添加到cell的flexigrid中。

2 个答案:

答案 0 :(得分:2)

我认为foo.getProperties()不保证订购的任何内容。但是Foo.constraints在运行时被覆盖而不是返回原始闭包,而是Map ConstrainedPropertydef props = [:] // [:] declares a LinkedHashMap, so order-preserving Foo.constraints.each { k, v -> props[k] = foo."${k}" } 个对象,并且此映射中的键保证在与约束闭包相同的顺序(这是脚手架如何能够使用约束排序来定义在scaffolded视图中呈现字段的顺序)。所以你可以做类似

的事情
{{1}}

答案 1 :(得分:0)

foo.getProperties().sort()或者如果没有好的方法按照您需要的顺序对属性进行排序,您可以随时在列表中定义属性的顺序以进行迭代。

def properties = ['name', 'description']
properties.each {
     cell.add(foo."$it")
}