我有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
属性的所有不同组合,但仍然无法在子页面中覆盖它。
这一般是错误的做法还是我错过了一些细节?
答案 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