当前位置:  开发笔记 > 前端 > 正文

如何动态地使用Grails 1.2渲染复杂的JSON?

如何解决《如何动态地使用Grails1.2渲染复杂的JSON?》经验,为你挑选了1个好方法。

我想使用Grails中的JSON渲染方法渲染复杂类型,类似于下面的JSON输出:

{"authors":[{"id":1,"name":"Author 1","books":[{"id":1,"name":"Book 1"},{"id":2,"name":"Book 2"}]},{"id":2,"name":"Author 2","books":[{"id":1,"name":"Book 1"},{"id":2,"name":"Book 2"}]}]}

我尝试使用以下代码执行此操作,其中Author和Book是包含属性id和name以及Author hasMany Books(association)的域类.

def results = Authors.list()
render(contentType:"text/json") {
  authors = array {
    for(a in results) {
      author id:a.id, name:a.name, books: array = {
        def bookresults = Book.findAllByAuthor(a)
        for(b in bookresults) {
          book id:b.id, name:b.name
        }
      }
    }
  }    
}

它仅适用于作者,但是当我尝试遍历每个作者的书籍并渲染它们时,代码就会失败.

有任何想法吗?

最终代码更新了问题

感谢Dave的回答,我最终得到了以下代码,它按预期工作:

def authors = []

for (a in Author.list()) {
  def books = []
  def author = [id:a.id, name:a.name, books:books]

  for (b in Book.findAllByAuthor(a)) {
    def book = [id:b.id, name:b.name]
    books << book
  }

  authors << author
}

def items = [authors:[authors]]
render items as JSON 

Dave Bower.. 10

我发现JSON构建器很难用于获得所需的结果,所以我更喜欢在地图和列表中生成结果然后渲染它们.

通过具有以下内容(警告:未经测试的代码!):

def results = []
Authors.list()?.each{ author ->
    def authorResult = [id:author.id, name:author.name]
    Book.findAllByAuthor(author)?.each { book ->
        authorResultput('books', [id:book.id, name:book.name])
    }
    results << authorResult
}
def authors = [authors: results]
render authors as JSON

我认为你使代码更容易阅读和重用,它应该做你想要的(我的错别字允许).

如果你总是会呈现你在同一个JSON格式作者和图书的你可以考虑注册BootStrap.groovy中的自定义JSON对象编组.总之类似的工作:

    JSON.registerObjectMarshaller(Author) {
        def returnArray = [:]
        returnArray['id'] = it.id
        returnArray['name'] = it.name
        return returnArray
    }

在作者身上拥有书籍属性也会让事情变得更容易!



1> Dave Bower..:

我发现JSON构建器很难用于获得所需的结果,所以我更喜欢在地图和列表中生成结果然后渲染它们.

通过具有以下内容(警告:未经测试的代码!):

def results = []
Authors.list()?.each{ author ->
    def authorResult = [id:author.id, name:author.name]
    Book.findAllByAuthor(author)?.each { book ->
        authorResultput('books', [id:book.id, name:book.name])
    }
    results << authorResult
}
def authors = [authors: results]
render authors as JSON

我认为你使代码更容易阅读和重用,它应该做你想要的(我的错别字允许).

如果你总是会呈现你在同一个JSON格式作者和图书的你可以考虑注册BootStrap.groovy中的自定义JSON对象编组.总之类似的工作:

    JSON.registerObjectMarshaller(Author) {
        def returnArray = [:]
        returnArray['id'] = it.id
        returnArray['name'] = it.name
        return returnArray
    }

在作者身上拥有书籍属性也会让事情变得更容易!

推荐阅读
殉情放开那只小兔子
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有