Тег g:include неправильно передает модель в представление

#grails

#grails

Вопрос:

Я боролся с этим уже несколько часов и пришел к выводу, что это может быть ошибка с 2.0.0.RC1.

Сначала я подумал, что это проект, над которым я работал, но затем я создал совершенно новый проект и смог воссоздать ошибку. Я использую grails 2.0.0.RC1.

Ошибка возникает, когда я пытаюсь включить объект модели в GSP, например:

/hello/index.gsp

  <p>This data is coming from the model:</p>
 <p>content: ${content}</p>
 <g:include model="${otherModel}" view="/hello/include.gsp" />
  

Теперь в моем действии у меня есть что-то вроде:

HelloController.groovy

 package helloworld

class HelloController {

        def index() {

    def model = [:]
    model.content = 'content...'

    def includeModel = [:]
    includeModel.content = 'includeModel...'

    model.otherModel = includeModel

    render( view:'index', model:model )
    }
}
  

Файл /hello/include.gsp содержит следующее:

/hello/include.gsp

 <p>This data is coming from the included model:</p>
<p>content: ${content}</p>
  

Но то, что отображается на странице, — это не то, что я ожидаю, это то, что отображается на странице:

http://localhost:8080/helloworld/hello/index

 This data is coming from the model:
content: content...
This data is coming from the included model:
content: content...
  

Есть идеи? Любая помощь приветствуется.

Спасибо, -Сезар

Ответ №1:

Возможно, это ошибка, но, согласно документам, тег include специально разработан для включения ответа другого контроллера / действия или представления в текущий ответ, а не только дополнительных GSP. Если вы хотите «включить» другой GSP на свою страницу, вам действительно следует использовать тег render. Я проверил, что ваш код корректно работает с тегом рендеринга и переименованием include.gsp в _include.gsp и созданием тега be <g:render model="${otherModel}" template="include" /> . Я получил следующий вывод:

Эти данные поступают из модели:

содержимое: содержимое…

Использование g: render: эти данные поступают из включенной модели:

содержимое: includeModel…

Я также попытался добавить другое действие к контроллеру, чтобы вернуть включенный контент и отобразить include.gsp, а затем использовать тег g:include для вывода этого на странице, и это сработало:

 def include() {
    def includeModel = [:]
    includeModel.content = 'includeModel...'
    includeModel      
}
  

А затем в index.gsp я добавил:

 <g:include action="include"/>
  

И я получил:

Эти данные поступают из модели:

содержимое: содержимое…

Использование g: render: Эти данные поступают из включенной модели:

содержимое: includeModel…

Используя g:include с действием, эти данные поступают из включенной модели:

содержимое: includeModel…

Кроме того, вам не нужно указывать render(view:’viewname, …) в вашем контроллере, если имя представления совпадает с именем метода в контроллере. Вы можете просто вернуть модель, и она автоматически выберет файл GSP с тем же именем, что и действие контроллера.

Все это, как говорится, по-прежнему кажется, что то, что вы пытаетесь сделать с тегом include, должно работать, и я не могу объяснить, почему это не так (и исходный код для тега не отображается внизу документов, как это должно быть). Я бы рекомендовал подать JIRA, хотя, если тег рендеринга вам не подходит.

Комментарии:

1. Я попробую вашу рекомендацию. Я просто надеялся, что мне не нужно реорганизовывать все эти включения в нашем веб-приложении, потому что я думал о упомянутом вами варианте вызова действия контроллера. Но это работало до обновления до 2.0.0.RC1.

2. В конце концов я последовал вашему совету. И переработал все способы использования g:include в g:render. Спасибо за рекомендацию. Я также поднял этот вопрос в списке рассылки пользователей grails, надеюсь, в какой-то момент там будет лучший ответ.

3. Это могло бы даже оправдать ДЖИРУ. По-прежнему кажется, что модель, передаваемая в атрибуте тега, должна переопределять модель содержащей страницы. По крайней мере, рефакторинг тем временем сработал!

4. Для этого я создал JIRA ticket GRAILS-8278 , и это было исправлено для версии 2.0-RC2.