Тег Grails не разрешает переменные в его теле - PullRequest
1 голос
/ 06 октября 2011

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

В моей библиотеке тегов у меня есть

def contentArea = {attrs, body ->           
  def domainObject = Class.forName("${attrs.contentType}", true, Thread.currentThread().contextClassLoader).newInstance() 
  def numberOfRows = !StringUtils.equals("${attrs.max}", "null")? new Integer("${attrs.max}") : new Integer("1");
  def results = domainObject.getByContentAreaKey("${attrs.contentAreaKey}", numberOfRows)   
  out << g.render(
    template: '/layouts/contentTag',
    model: [contentAreaKey: attrs.contentAreaKey, results : results, contentNamespace: "${attrs.contentAreaKey}" + "_contentList", body:body()])
  out << body()
}

в _contentTag.gsp, макетеis:

<b>In tag layout, </b>
<g:set var="${contentNamespace}" value="bobby"/>
contentNamespace = ${contentNamespace}<br/><!-- prints "minicontent_contentList" -->
minicontent_contentList = ${minicontent_contentList}<br/> <!-- prints "bobby" -->

И в вызывающем gsp тег называется:

<mynamespace:contentArea var="myVar" contentAreaKey="minicontent" contentType="com.my.test.MiniContentType">
  <br/>Test Text<br/>
  <b>in calling GSP,</b> 
  contentNamespace = ${contentNamespace}<br/><!-- prints nothing -->
  minicontent_contentList = ${minicontent_contentList}<br/><!-- prints nothing -->          
</mynamespace:contentArea>

contentNamespace и minicontent_contentList не разрешаются в теле тега.Возможно ли разрешить переменные?Если да, то как мне это сделать?

В случае, если это поможет с ответом, у меня есть страница с несколькими небольшими областями контента, которые я хочу администрировать через другой контроллер.Все области контента имеют схожие данные (текст, ссылка, графика и т. Д.), Но макеты будут другими.Я использовал макеты sitemesh, чтобы заблокировать страницу, и вызывающий gsp представляет один из этих блоков контента sitemesh.

Я очень плохо знаком с grails и обращаюсь за помощью по SO, поэтому я совершенно готов принятькритика, но, пожалуйста, будьте нежны.:)

1 Ответ

1 голос
/ 06 октября 2011

body, как передано в параметре, является Closure, который преобразует свои методы и параметры в место, где оно было объявлено, которое здесь будет основным gsp. Вы можете попробовать установить delegate из body для библиотеки тегов и установить resolveStrategy в Closure.DELEGATE_FIRST. Это должно позволить вам решить contentNamespace.

def contentArea = {attrs, body ->
    ...
    def contentNamespace = "${attrs.contentAreaKey}" + "_contentList"
    out << g.render(
    ...
    body.delegate = this
    body.resolveStrategy = Closure.DELEGATE_FIRST
    out << body()
}

Решить minicontent_contentlist будет сложнее, так как я не уверен, как указать шаблон в качестве делегата. Вы можете попытаться определить переменную в библиотеке тегов и передать ее в шаблонную модель, а затем назначить значение minicontent_contentlist этому переданному объекту, что может обновить значение обратно в коде библиотеки тегов, чтобы resolveStrategy работал при условии, что это тот же объект, переданный по ссылке.

def contentArea = {attrs, body ->
    ...
    def minicontent_contentList
    out << g.render( ..., model:[minicontent_contentList:minicontent_contentList])
    ...delegate and resolveStrategy stuff...
}

<b>In tag layout, </b>
<g:set var="minicontent_contentlist" value="bobby"/>
contentNamespace = ${contentNamespace}<br/><!-- prints "minicontent_contentList" -->
minicontent_contentList = ${minicontent_contentList}<br/> <!-- prints "bobby" -->

В качестве окончательного варианта вы можете попробовать назначить delegate/resolveStrategy внутри gsp curlies (${}) в шаблоне, чтобы увидеть, назначает ли объект шаблона параметру delegate.

...