Использование доменных методов в Grails JSON View

Я создал приложение Grails 4.0, используя профиль VUE, и использую представления JSON (http://views.grails.org/latest/#_json_views) и все работает правильно, но я не нашел способа использовать доменные методы в шаблоне .gson

Пример, который отлично работает:

Класс домена Person.groovy

class Person {

    String firstName
    String lastName

    String fullName(){
        return "$firstName $lastName"
    }
}

PersonController

class PersonController {

    def show(){
      respond Person.get(params.id)
    }

}

/views/человек/_person.gson

model {
    Person person
}

json {
    lastName person.lastName
    firstName person.firstName
    //fullName person.fullName() -- this line doesn't compile
}

Это базовый пример того, что я пытаюсь сделать, но я не могу ничего подобного скомпилировать, и я не видел в документах, возможно ли это вообще. Я также попытался вызвать метод в классе домена «getFullName()», а затем в файле gson выполнить «fullName person.fullName», но это тоже не сработало.

Есть ли способ использовать методы класса домена в файле .gson?

ОБНОВЛЕНИЕ: это пример журнала трассировки стека с функцией getFullName().

[Static type checking] - No such property: fullName for class: Person
 @ line 8, column 8.
       fullName person.fullName
          ^

1 error

    at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:311)
    at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1102)
    at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:645)
    at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:623)
    at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:600)
    at grails.views.ResolvableGroovyTemplateEngine$_createTemplate_closure2.doCall(ResolvableGroovyTemplateEngine.groovy:430)
    ... 71 common frames omitted

И это пример метода fullName()

[Static type checking] - Cannot find matching method Person#fullName(). Please check if the declared type is correct and if the method exists.
 @ line 8, column 8.
       fullName person.fullName()
          ^

1 error

person user779643    schedule 20.08.2019    source источник
comment
Что значит не компилируется? Есть ли ошибки или трассировки стека, которыми можно поделиться?   -  person cfrick    schedule 21.08.2019
comment
@cfrick Вопрос был обновлен с учетом ошибок из файла журнала.   -  person user779643    schedule 21.08.2019
comment
Вы уже пробовали использовать транзиенты? Похоже, это именно то, что вы ищете: docs.grails.org/ последний/ref/Домен%20Classes/transients.html   -  person Joshua Moore    schedule 21.08.2019
comment
Переходные процессы @JoshuaMoore не будут иметь никакого отношения к ошибке компиляции. Они были бы актуальны, если бы в его доменном классе был метод с именем getFullName(), но это не то, что у него есть. Что бы я сделал, так это иметь метод getFullName(), сделать fullName переходным, а затем в ссылке представления person.fullName, но причины, которые являются лучшей идеей, чем когда он/она делает, не помогают устранить ошибку компиляции, которую задает вопрос о.   -  person Jeff Scott Brown    schedule 21.08.2019
comment
@JeffScottBrown Это то, что я предлагал. Была более чистая реализация с использованием переходных процессов. Однако вы правы. Я не отвечал на вопрос об ошибке компиляции.   -  person Joshua Moore    schedule 21.08.2019
comment
Это то, что я предлагал. Была более чистая реализация с использованием переходных процессов. - Я понимаю. Возможно, это то, что ищет спрашивающий. Я думал, они хотят знать об ошибке компиляции. Может быть моя ошибка.   -  person Jeff Scott Brown    schedule 21.08.2019


Ответы (1)


Одно из сообщений об ошибках, которые вы там показываете, включает следующее:

[Static type checking] - No such property: fullName for class: Person
 @ line 8, column 8.
       fullName person.fullName
          ^

1 error

Похоже, вы имеете в виду person.fullName вместо person.fullName(). person.fullName работало бы, если бы в классе Person был метод с именем getFullName(), но у вас его нет.

См. проект по адресу https://github.com/jeffbrown/fullnamequestion.

https://github.com/jeffbrown/fullnamequestion/blob/81cb45f176f887edf90de783a976c48154c3f9bc/server/grails-app/views/person/_person.gson

import fullnamequestion.Person

model {
    Person person
}

json {
    lastName person.lastName
    firstName person.firstName
    fullName person.fullName()
}

Это отлично работает:

~ $ git clone https://github.com/jeffbrown/fullnamequestion.git
Cloning into 'fullnamequestion'...
remote: Enumerating objects: 144, done.
remote: Counting objects: 100% (144/144), done.
remote: Compressing objects: 100% (120/120), done.
remote: Total 144 (delta 5), reused 144 (delta 5), pack-reused 0
Receiving objects: 100% (144/144), 188.53 KiB | 2.62 MiB/s, done.
Resolving deltas: 100% (5/5), done.
~ $ 
~ $ cd fullnamequestion/
~ $ ./gradlew server:bootRun

> Task :server:bootRun

Grails application running at http://localhost:8080 in environment: development
<==========---> 83% EXECUTING [18s]
> :server:bootRun

Отправьте запрос на визуализацию вида:

~ $ curl http://localhost:8080/person/1
{"lastName":"Lee","firstName":"Geddy","fullName":"Geddy Lee"}
person Jeff Scott Brown    schedule 21.08.2019
comment
Это правильно, и просмотр вашего примера проекта помог. Одна из проблем, которую я обнаружил, заключалась в том, что если бы в моем доменном классе я вызвал свой метод def myMethod(), он выдал бы мне NoSuchMethodError, но если я назову его String myMethod, он будет работать правильно. Я делал первое изначально - person user779643; 21.08.2019
comment
Это не имеет смысла для меня, и я не могу воспроизвести это. Тип возвращаемого значения метода не должен иметь значения. - person Jeff Scott Brown; 21.08.2019
comment
Ваш комментарий в сочетании с некоторыми элементами в других местах этого вопроса подсказывает мне, что вы можете запутаться в свойствах и методах. per.fullName будет оценивать значение свойства fullName, которое отличается от вызова per.fullName(), который вызовет метод с именем fullName. - person Jeff Scott Brown; 21.08.2019
comment
github.com/kingaaronm/fullnamequestion — я разветвил ваш проект, изменив домен/Person.groovy на показать, что я имею в виду - person user779643; 21.08.2019
comment
@user779643 user779643 Похоже, ваш код работает. См. jeffscreencasts.s3.amazonaws.com/user779643.mp4. - person Jeff Scott Brown; 21.08.2019
comment
Вы вносите изменения в класс домена во время работы приложения и динамически перезагружаете эти изменения? - person Jeff Scott Brown; 21.08.2019
comment
Если вы меняете сигнатуру метода в классе домена во время работы приложения, это объясняет поведение, которое вы видите. Проблема не в том, что вы не можете вызывать методы класса предметной области из представления JSON. Проблема связана с проблемами перезагрузки класса. - person Jeff Scott Brown; 21.08.2019