【问题标题】:Grails <g:set> tag not executed inside custom tagGrails <g:set> 标签未在自定义标签内执行
【发布时间】:2012-10-10 16:24:49
【问题描述】:

我有一个名为&lt;mk:pageViewTag&gt; 的自定义标签,它首先呈现.gsp 模板,然后在里面执行它的主体:

标签库(UtilTagLib.groovy):

string namespace = "mk"

def pageViewTag = { attrs, body ->
    out << render(template: '/templates/pageTagView') {
        body()
    }
}
...

我渲染的模板(templates/_pageTagView.gsp):

<body>
    ${ body() }
    ...
</body>

GSP 我在 (test.gsp) 上使用自定义标签:

<mk:pageViewTag>
    <g:set name="test" value="${1}">
    ${test?:0} %{--Here, I got 0. Variable test does not exist!--}%
</mk:pageViewTag>

除了&lt;g:set&gt; 标记之外,一切都运行良好,它没有按我的预期执行。 Grails 根本看不到我声明的变量。

在上面的示例中,我声明了变量 test 并使用整数 1 对其进行了初始化。作为输出,我得到了0

根据Grails Docs我可以使用scope属性,设置为request就解决了问题。

有没有其他方法可以解决它?为什么会这样?

注意:mk:pageViewTag 的内部很大,所以我不能在外面的任何地方声明一个变量。

【问题讨论】:

  • 可能是评估时间。也许通过从 taglib 调用它来复制标签内的集合?
  • @Neoryder 计时,也许。我希望我能按照你的建议做,但是下面的逻辑并不像我在示例中那样直截了当。

标签: grails taglib


【解决方案1】:

不完美,但不需要技巧的快速解决方案(嗯,几乎)。
我先执行body,然后将其包含为模板主体。

标签库(UtilTagLib.groovy):

string namespace = "mk"

def pageViewTag = { attrs, body ->

    // Render body ahead!
    String renderedBody = body()

    out << render(template: '/templates/pageTagView') {
        renderedBody
    }
}
...

【讨论】:

  • 不幸的是,当直接从视图/模板中使用渲染标签时,这无济于事,例如:&lt;g:render template='xx'&gt;&lt;g:set...&gt; ...&lt;/render&gt; 和 _xx.gsp:&lt;blah&gt;${body()}&lt;/blah&gt;(参见 GRAILS-4736
【解决方案2】:

g:set 需要一个 var 属性而不是名称:http://grails.org/doc/2.2.1/ref/Tags/set.html

【讨论】:

    【解决方案3】:
    string namespace = "mk"
    
    def pageViewTag = { attrs, body ->
      out << render(template: '/templates/pageTagView', model:[body: body()])
    }
    

    模板/_pageTagView.gsp:

    <body>
      ${body}
      ...
    </body>
    

    【讨论】:

      【解决方案4】:

      我在模板中声明了一个 grails 变量,并在父 gsp 文件(包含模板的地方)中使用了它。

      例如:Parent.gsp 包含模板:_child.gsp,其中包含“&lt;g:set var="a" value="${1}" /&gt;”。在 Parent.gsp 中打印变量“a”会呈现“null”。

      因此,我们发现在渲染模板时插入带有变量的模板或设置变量不起作用。因为渲染模板需要时间并且与父页面异步。在渲染完成之前,我们无法确定变量初始化。

      如果范围设置为“请求”,那么我们说这个变量应该在整个请求周期内都是可见的,并且它们存储在请求中以供进一步处理或访问。 建议使用&lt;g:set var="a" value="${1}" scope='request'/&gt;&lt;g:set var="a" value="${1}" scope='session'/&gt;

      请参考以下链接了解如何使用范围:

      grails scope questions - page, request, flash

      How to use grails <g:set> tag session scope?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-26
        • 2015-09-13
        • 1970-01-01
        • 2019-12-30
        • 2017-10-19
        • 1970-01-01
        • 2012-07-13
        • 1970-01-01
        相关资源
        最近更新 更多