Как визуализировать различные типы объектов в одном списке с помощью Grails JSON представлений? - PullRequest
0 голосов
/ 25 октября 2018

У меня есть структура классов:

class A {
...
}

class B extends A {
...
}

class C extends A {
...
}

Нет, в контроллере я получаю список объектов смешанных типов:

A[] objects = bethodTpFetchTheList()

В представлении янужно отобразить весь список, но мне нужно использовать другой шаблон для разных типов.

Возможно ли это вообще?

Когда у меня был один тип, я использовал для рендеринга json thisпуть:

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

Другой с определенным шаблоном, создаст пустой объект.

1 Ответ

0 голосов
/ 25 октября 2018

Это действительно зависит от подробностей, но это может помочь.

Идеально было бы организовать данные в отдельные списки обратно на уровне контроллера или сервиса и сделать слой представления более простым, но ответить навопрос как задано, проект в 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 по-другому, если вы можете предоставить желаемый результат, это поможет.

...