【问题标题】:Include boolean params with g:include are passed as Strings to the included view包含带有 g:include 的布尔参数作为字符串传递给包含的视图
【发布时间】:2019-01-17 01:03:11
【问题描述】:

我不知道以下更改是有问题还是有意为之。

<g:include view="line.gsp" params="['label':'test', 'progress':false]"/>

那么 line.gsp aways 中的表达式计算结果为 true,因为 'progress' 参数的类型是字符串,而不是布尔值。

  class is: ${params.progress.getClass()}
  <g:if test="${params.progress}">
   this should not be displayed
 </g:if>

请注意,这同样适用于其他类型,而不仅仅是布尔值。 我正在使用 grails 3.3.8 这在 grails 2.5.2 中没有发生。

我在网上没有找到任何关于此的信息,所以我在这里问。谢谢。

编辑:

正如 Daniel 所建议的,我也尝试过使用 grails 3.3.2。 我刚刚使用 grails create-app 创建了一个应用,并修改了现有的 index.gsp 以包含 line.gsp,如上面的代码所示。

这是一个截图:

【问题讨论】:

  • 这至少在 grails 3.3.2 中按预期工作。我刚刚测试了您的确切示例,${params.progress.getClass()} 是布尔值,它在 if 块中正确评估。也许还有其他事情发生?您是否已经将 progress 参数传递到父视图中?
  • 嗯,我试过 3.3.8、3.0.0 和 grails 2.5.2。我使用 grails create-app 从头开始​​创建应用程序。我刚刚创建了一个包含问题代码的简单 line.gsp 文件,然后修改了现有的 index.gsp 文件以包含 line.gsp 文件。我没有做任何其他改变。很奇怪。
  • 如果在 line.gsp 中输出${params.progress} 会发生什么?还是${params.progress.getClass()}
  • grails 2 和 3 都显示为 true,但 grails 3 显示 java.lang.String() 而 grails 2 显示 java.lang.Boolean。这就是我注意到进度被解释为字符串的原因,因为最初我在 gsp 中有一个不同的错误,实际上是由这个错误引起的。我也会尝试使用 grails 3.3.2。谢谢。
  • @Daniel 我也尝试过使用 grails 3.3.2,即使在不同的系统上,我也得到了相同的结果。我用截图编辑了我的问题。

标签: grails grails-3.3.x


【解决方案1】:

我知道您已经找到了解决此问题的方法,但是让我感到困扰的是您的代码与我的代码不同,因此我决定进一步调查,以防其他人遇到此问题。

正如这里的其他人所提到的,params.anything 通常会返回一个字符串值。这是因为 params 通常被编码为 URI 参数(如 ?progress=false),而不是自动装箱到任何其他类型。 (这是完全合理的;Grails 没有好方法知道它们应该是什么类型。)但是,可以(有时也是合理的)从像 render view: whatever, model: [your: model, params: params] 这样的控制器渲染您的视图或模板,其中您特别包括模型中的参数。 (也许您有很多不需要在模型中单独重新创建的参数。)在这种情况下,params 映射将作为 URI 参数 (?progress=false) 和页面范围的模型条目 (params: [进度:Boolean.FALSE])。页面范围优先于 URI 参数,因此您的类型将被保留。

在我的测试中,我将您的代码添加到了一个现有页面,我已经将参数传递给模型,因此也为新添加的参数保留了类型。 (请注意,一旦参数在页面范围内,它们也用于包含的模板或视图。)因此,我看到了 Boolean 的进度类型,而在一个基本示例中,它将是 String 类型。

TL/DR:假设参数是字符串,或者在渲染时在页面范围模型中显式包含参数。

【讨论】:

  • 谢谢!这是有道理的:)
【解决方案2】:

是的,这是真的。当您调用params.something 时,您实际上是在访问 GrailsParameterMap,它是一个 Map。因此,您的条件实际上评估为 Map->get() ,它将是 Object->toString() ,当然这是真的,因为它不为空也不为空。所以解决方案如下:

<g:if test="${params.getBoolean("progress")}">
   this should not be displayed
</g:if>

【讨论】:

  • 是的,我注意到了。我唯一担心的是这在 grails 3 中是如何改变的。
  • 为什么你认为 GrailsParameterMap 必然返回一个字符串值?
  • 我只在这种情况下提及。您可以通过以下方式检查:${params.progress?.getClass()},它将打印:class java.lang.String。是的:GrailsParameterMap 可以像往常一样在其他场景中存储 diff 类型的 Object in value。
【解决方案3】:

你可以这样测试

<g:if test="${params.progress && params.progress == 'false'}">
   this should not be displayed
 </g:if>

【讨论】:

  • 是的,我注意到了。我唯一担心的是这在 grails 3 中是如何发生变化的。将应用程序从 grails 2 迁移到 grails 3 涉及更改以前在 grails 2 中工作的所有此类事件。
猜你喜欢
  • 2011-12-29
  • 2012-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多