grails - 如何使用grails json View 在同一列表中呈现不同类型的对象?

标签 grails gson json-view

我有一个类的结构为:

class A {
...
}

class B extends A {
...
}

class C extends A {
...
}

不,在 Controller 中,我正在获取混合类型的对象的列表:
A[] objects = bethodTpFetchTheList()

在 View 中,我需要呈现整个列表,但是我需要对不同类型使用不同的模板。

可能吗

当我只有一个类型时,我曾经用这种方式渲染json:
json tmpl.object(objects)

有没有一种方法可以手动遍历列表并根据类型做出决策?

某些进度
所以我明白了这一点:
json utilizations, { ToolUtilization utilization ->
    if (utilization.type == ToolType.TOOL_40_PRINCIPLES) {
        tmpl.'/fortyPrinciplesUtilization/utilization'(utilization)
    } else if (utilization.type == ToolType.RRM){
        tmpl.'/rrmUtilization/utilization'(utilization)
    }
}

它有点用,但是却呈现出空对象...

更多进步

看来,如果我使用g.inline,它会部分起作用,但不会拾取模板。因此,如果我这样做:
json(utilizations) { ToolUtilization utilization ->
    if (utilization.type == ToolType.TOOL_40_PRINCIPLES) {
        g.inline(utilization) <= here it renders the object with a default renderer.
    } else if (utilization.type == ToolType.RRM){
        g.inline(template:'/rrmUtilization/utilization', model:[utilization: utilization])
    }
}

另一个已定义模板的对象将生成一个空对象。

最佳答案

它确实取决于细节,但这可能会有所帮助。

理想的做法是将数据组织回到 Controller 或服务层中的单独列表中,并使 View 层更简单,但要回答所提出的问题,https://github.com/jeffbrown/renderjsonobjects上的项目显示了一种实现方法。

感兴趣的文件:

https://github.com/jeffbrown/renderjsonobjects/blob/master/grails-app/controllers/renderjsonobjects/DemoController.groovy

package renderjsonobjects

class DemoController {
    static responseFormats = ['json', 'xml']

    def index() {
        // the intent here is just to simulate a list of
        // instances of different types...
        def results = []
        results << new Person(name: 'Zack')
        results << new Address(town: 'St. Louis')
        results << new Person(name: 'Matt')
        results << new Address(town: 'San Jose')

        respond view: 'index', model: [theData: results]
    }
}

https://github.com/jeffbrown/renderjsonobjects/blob/master/grails-app/views/demo/_person.gson是用于呈现Person的模板。
import renderjsonobjects.Person

model {
    Person person
}

json {
    name person.name
}

https://github.com/jeffbrown/renderjsonobjects/blob/master/grails-app/views/demo/_address.gson是用于呈现Address的模板:
import renderjsonobjects.Address

model {
    Address address
}

json {
    town address.town
}

https://github.com/jeffbrown/renderjsonobjects/blob/master/grails-app/views/demo/index.gson遍历异构List并为不同类型呈现不同的模板。同样,这可能并不是解决您实际问题的最佳解决方案,但这是解决问题的一种方法。
import renderjsonobjects.Address
import renderjsonobjects.Person

json {
    Map theModel = (Map)binding.variables.model
    List data = (List)theModel.theData
    people tmpl.person(data.findAll { it instanceof Person })
    addresses tmpl.address(data.findAll { it instanceof Address})
}

这将导致如下所示:
$ curl http://localhost:8080/demo
{"people":[{"name":"Zack"},{"name":"Matt"}],"addresses":[{"town":"St. Louis"},{"town":"San Jose"}]}

基于评论的更新:

参见https://github.com/jeffbrown/renderjsonobjects/commit/13aea5db090cd38a2039e08fb9b675630d5bf565

这使得https://github.com/jeffbrown/renderjsonobjects/blob/master/grails-app/views/demo/index.gson如下所示:
json (((Map)binding.variables.model).theData)

这导致呈现以下内容:
[[{"name":"Zack"},{"town":"St. Louis"},{"name":"Matt"},{"town":"San Jose"}]]

我认为这满足了所问的问题。如果您希望看到不同的JSON结构,则可以提供所需的输出,这将有所帮助。

关于grails - 如何使用grails json View 在同一列表中呈现不同类型的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52984001/

相关文章:

grails - 运行Grails CLI : No profile found for name [web].时发生错误(使用--stacktrace查看完整跟踪)

json - Kotlin json解析where "val $t: String"

json - 如何在不定义内部模板的情况下使用Grails JSON View ?

java - 使用 GROOVY SQL 从 SQL SERVER 存储过程获取结果集

.net - 如何使用Grails调用WCF .net Web服务

android - 原语 Realm 列表的 Gson 反序列化

java - 使用 GSON 解析 map 的 JSON map

java - 类和字段级别@JsonView注释和对象映射器

grails - 在tagLib中使用方法调用语法时,如何将id传递给链接?