Grails的getProperties方法并不总是以正确的顺序返回属性 [英] Grails getProperties method does not always return properties in the correct order

查看:176
本文介绍了Grails的getProperties方法并不总是以正确的顺序返回属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  class Foo {
名称
描述

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

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

  {
page:1,
total:1,
rows:[
{
id:1,
cell:[
1,
Foo 1的名称,
Foo 1的描述
]
},
{
id :2,
cell:[
2,
Foo 2的名称,
Foo 2的描述
]



$ $ $
$ b

为了让我的 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 - > //有时会得到foo.getProperties()。each()返回foo.description,然后返回foo.name而不是foo.name,然后根据需要返回foo.description。
cell.add(value.toString())
}

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

将结果呈现为JSON

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

放入我的flexigrid的描述列中, / code> domain类,因此 getProperties 会以正确的顺序返回,但它不起作用。 如何确保 getProperties 以可预测的顺序返回属性?
$ b

这是我如何解决此问题:

  def items = Foo.getAll()

for(item in item){
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 获取约束映射,其中每个约束都是集合$ UnmodifiableMap $ UnmodifiableEntrySet $ UnmodifiableEntry 的一个实例。经过测试,我发现这张地图总是按照我输入的顺序返回我的 Foo 静态约束(也由Ian确认)。现在只有在 Foo.constraints 中的的属性将被添加到我不认为 foo.getProperties 对于flexigrid。

解决方案

()保证了有关排序的任何信息。但是 Foo.constraints 在运行时被覆盖,不会返回原始闭包,而是 Map ConstrainedProperty 对象和该映射中的键 保证与约束闭包的顺序相同(这是脚手架如何使用约束排序来定义在脚手架视图中呈现字段的顺序)。所以你可以做一些像

  def props = [:] // [:]声明一个LinkedHashMap,所以order-preserving 
Foo.constraints.each {k,v - >
道具[k] = foo。$ {k}
}


I have a class that looks like this:

class Foo {
    name
    description

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

I want to add display instances of my class in a Flexigrid. When data is sent to a flexigrid it needs to be in a format like JSON or XML... I have chosen JSON. Flexigrid expects JSON arrays it receives to have the following format:

{
    "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"
            ]
        }
    ]
}

To get my Foo objects into this format I do something similar to this:

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

The problem is that every once in a while foo.getProperties().each() returns foo.description then foo.name resulting in foo.description being put in the name column of my flexigrid and foo.name being put in the description column of my flexigrid for a specific row.

I tried specifying constraints in the Foo domain class so the getProperties would return in the correct order, but it didn't work. How can I make sure getProperties returns properties in a predictable order?

This is how I fixed this issuse:

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() )
        }
    }
}

So Foo.constraints gets a map of constraints where each constraint is an instance of Collections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry. After testing I have found this map always returns my Foo static constraints in the order I entered them (also confirmed by Ian). Now only the properties of the item which are in Foo.constraints will be added to the cell for flexigrid.

解决方案

I don't think foo.getProperties() guarantees anything about the ordering. But Foo.constraints is overridden at runtime to return not the original closure, but a Map of ConstrainedProperty objects and the keys in this map are guaranteed to be in the same order as the constraints closure (this is how scaffolding is able to use the constraints ordering to define the order in which fields are presented in the scaffolded views). So you could do something like

def props = [:] // [:] declares a LinkedHashMap, so order-preserving
Foo.constraints.each { k, v ->
  props[k] = foo."${k}"
}

这篇关于Grails的getProperties方法并不总是以正确的顺序返回属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆