【问题标题】:Cannot modify a value in a Soy template无法修改大豆模板中的值
【发布时间】:2014-05-19 06:50:09
【问题描述】:
{let $first: 10 /} // this is a single line soy comment
{if $first > 5 }
{$first}<br/>
{let $first:$first-1 /}
{/if}
{$first}
我试过了,它打印:10 10
理想情况下,它应该打印:10 9 ..
你能找出我的代码有什么问题吗?
【问题讨论】:
标签:
google-closure
google-closure-templates
【解决方案1】:
首先,您不能真正覆盖$first 的值。 documentation 状态由 let 定义的局部变量是不可修改的。这是因为每当您使用 let 为值设置别名时,都会在编译的输出中创建一个新变量。此外,soy 表达式的作用域规则与 Javascript 中的不同(但您可以认为 {let} 与 ECMAScript 6 的 let 语句具有相似的语义,即非提升,块作用域)。
在您的代码中:
{let $first: 10 /} /* 1 */
{if $first > 5}
{$first}<br/>
{let $first¹: $first-1 /} /* 2 */
/* 3 */
{/if}
{$first} /* 4 */
发生了什么:
在 (1) 中,$first 是值 10 的别名。引入了一个变量来保存这个值。
-
在(2)中:
右手: $first 从 (1) 中获取值,因为它是在父块中定义的。
左手: $first¹ 被别名为 $first - 1 = 10 - 1 = 9 的值。因为$first 的定义不能被覆盖,所以引入了与(1)不同的新变量。有两点需要注意:
一个。 $first¹ 的值为 9,但在此 sn-p 中从不读取。
b. $first¹ 仅“存在”在它定义的块内,即在 {if...} 内。事实上,如果你在 (3) 中插入{$first},它会输出 9。
在(4)中,$first¹ 的值超出了{if} 块引入的范围,无法再读取,因此(1)中的$first 是唯一可见的,产生 10。它在编译输出中使用与 (1) 相同的变量。