Grails的getProperties方法并不总是以正确的顺序返回属性 [英] Grails getProperties method does not always return properties in the correct order
问题描述
class Foo {
名称
描述
static constraints = {
name()
description()
}
}
我想在 Flexigrid 中添加我的类的显示实例。当数据发送到flexigrid时,它需要采用JSON或XML格式...我选择了JSON。 Flexigrid期望它收到的JSON数组具有以下格式:
{
放入我的flexigrid的描述列中, / code> domain类,因此
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
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()
returnsfoo.description
thenfoo.name
resulting infoo.description
being put in the name column of my flexigrid andfoo.name
being put in the description column of my flexigrid for a specific row.I tried specifying constraints in the
Foo
domain class so thegetProperties
would return in the correct order, but it didn't work. How can I make suregetProperties
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 ofCollections$UnmodifiableMap$UnmodifiableEntrySet$UnmodifiableEntry
. After testing I have found this map always returns myFoo
static constraints in the order I entered them (also confirmed by Ian). Now only the properties of theitem
which are inFoo.constraints
will be added to thecell
for flexigrid.解决方案I don't think
foo.getProperties()
guarantees anything about the ordering. ButFoo.constraints
is overridden at runtime to return not the original closure, but aMap
ofConstrainedProperty
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 likedef props = [:] // [:] declares a LinkedHashMap, so order-preserving Foo.constraints.each { k, v -> props[k] = foo."${k}" }
这篇关于Grails的getProperties方法并不总是以正确的顺序返回属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文