我有一个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属性的所有不同组合,但仍然无法在子页面中将其覆盖。

这通常是错误的方法还是我错过了一些细节?

最佳答案

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

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

另一点是,您仍然需要使用request范围来访问页面之间的相同变量(这非常直观)。

因此,解决方案变为:

首先在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>

关于grails - 在<g:layoutBody>中覆盖Grails <g:set>变量的值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17343529/

10-14 06:19