在<g:layoutbody> </g:layoutbody> </g:set>中覆盖Grails <g:set>变量的值

时间:2013-06-27 12:43:41

标签: grails gsp

我有layout.gsp我在其中为控件(比如横幅)定义了一些标记,可能会显示在任何页面上(或者可能不会)。

<g:set var="showBanner" value="${...}" scope="page|request|flash|session"/>
<!-- Some more logic that may g:set showBanner var -->

<g:layoutBody/>

<g:if test="${[flash|request|???].showBanner}">
   <div id="banner">...</div>
</g:if>

我们的想法是让由<g:layoutBody>呈现的页面决定是否需要横幅。因此,一个页面可能决定始终显示横幅,如下所示 - page1.gsp:

<g:set var="showBanner" value="${true}" scope="page|request|flash|session"/>

另一个页面决定永远不会在其上显示横幅,如下所示 - page2.gsp:

<g:set var="showBanner" value="${false}" scope="page|request|flash|session"/>

不幸的是,这种方法对我不起作用。我尝试了scope属性的所有不同组合,但仍然无法在子页面中覆盖它。

这一般是错误的做法还是我错过了一些细节?

2 个答案:

答案 0 :(得分:3)

我发现我做错了什么。问题是,在<{em> layout.gsp代码运行之前评估在包含页面内设置的变量,而不是在<g:layoutBody/>代码插入时(或调用) )。

换句话说,依赖关系在布局之前呈现,而不是在遇到布局指令时。对某些人来说这可能是直观的,但对其他人来说却不是这样(不适合我)。

另一点是你仍然需要使用request范围访问页面之间的相同var(非常直观)。

因此,解决方案变为:

首先在page1.gsp

<g:set var="showBanner" value="${true}" scope="request"/>

然后在layout.gsp

<!-- Doesn't matter were you put it, always evaluated first -->
<g:layoutBody/>

<g:if test="request.showBanner == null"> <!-- if not set by children page -->
    <g:set var="showBanner" value="${...}" scope="request"/>
    <!-- Some more logic that may g:set request.showBanner var -->
</g:if>

<g:if test="${request.showBanner}">
   <div id="banner">...</div>
</g:if>

答案 1 :(得分:0)

你在拦截器中设置变量怎么样?如下所示:Accessing the model from a layout view in Grails