我正在玩Angularjs,可能我在滥用它.我使用分号在这样的角度表达式中有几个语句(jsFiddle):
<tr ng-repeat="i in [1, 2, 3, 4]">
<td>i = {{ m = k; k = j; j = i + 1; i}}</td>
<td>j = {{j}}</td>
<td>k = {{k}}</td>
<td>m = {{m}}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)
起初,我认为在计算之前k会有值,但显然它不会像这样工作.结果是:ji+1
i = 1 j = 2 k = 2 m = 2
i = 2 j = 3 k = 3 m = 3
i = 3 j = 4 k = 4 m = 4
i = 4 j = 5 k = 5 m = 5
Run Code Online (Sandbox Code Playgroud)
因此很明显,分配j到k和k到m,并不意味着值复制,但这些名称绑定在一起.我能理解.但是如果我删除显示k(jsFiddle)值的行,会发生奇怪的事情:
<tr ng-repeat="i in [1, 2, 3, 4]">
<td>i = {{ m = k; k = j; j = i + 1; i}}</td>
<td>j = {{j}}</td>
<td>m = {{m}}</td>
</tr>
Run Code Online (Sandbox Code Playgroud)
我正在获得:
i = 1 j = 2 m =
i = 2 j = 3 m =
i = 3 j = 4 m =
i = 4 j = 5 m =
Run Code Online (Sandbox Code Playgroud)
也就是说m,尽管它被绑定j(通过k),但不包含任何值.它可能是因为k它本身没有被评估.
我的问题是:它不是AngularJS中的错误吗?当然k,即使它没有直接显示,也应该评估它是否在绑定链中.或者我误解了什么?
我知道它可能不是使用AngularJS的惯用方法,但我想真正理解表达式引擎,我无法解释这种行为.
这里有几个相互作用的问题.
首先,你的陈述是向后排序的:你在设置j之前设置k = j,这导致它未被定义.
其次,更重要的是,不应使用插值表达式("{{}}"中的表达式)来改变范围的状态.这有一个很好的理由:
插值的工作方式是,当它编译你的html时,angular会scope.$watch在每个插值表达式上注册a .
但是这些观察到的表达式可以在摘要期间多次执行:每当侦听器修改范围时,它会使角度再次通过该范围上的监视.出于这个原因,观看的表达式确实应该是"幂等的":即,它们应该没有副作用/导致状态没有变化.这是来自以下文档$watch:
每次调用$ digest()时都会调用watchExpression,并且应该返回将要监视的值.(由于$ digest()在检测到更改时重新运行,因此watchExpression可以每$ digest()执行多次,并且应该是幂等的.)
具体来说,这是你的例子中发生的事情.首先,它与转发器无关.每个ng-repeat项目都有自己的范围,所以这里发生的事情等同于这个更简单的例子:
<div ng-app>
{{ i = 42 }}<br>
i = {{ m = k; k = j; j = i+1; i }}<br>
j = {{j}}<br>
k = {{k}}<br>
m = {{m}}<br>
</div>
Run Code Online (Sandbox Code Playgroud)
(这是小提琴)
摘要的进行如下:
{{ i = 42 }}设置scope.i为42,并在文档中显示"42".但是,由于范围已经改变,所以还设置了" 脏 "标志,这意味着我们将再次循环通过手表(参见下面的步骤5){{ m = k; k = j; j = i+1; i }}集scope.m和scope.kto undefined,以及scope.j43,并在文档中显示"42". {{ j }}在文档中显示"43".{{ k }}然后{{ m }}在文档中只显示"",因为它们当前未定义.{{ m = k; k = j; j = i+1; i }},k = j起作用,因为j存在; 所以k被赋值为43. {{ k }}这个时候,它的值已从undefined更改为2,因此脏标志再次设置,但现在文档显示"k = 2".但是,{{ m }}仍然未定义.{{ m = k; k = j; j = i+1; i }}导致m被设置为43. 切向地,我在浏览摘要代码时遇到了一个有趣的事情:看起来脏标志在第一次通过手表时始终设置为true,因为从未检查过的手表没有记录"最后"值.看起来这样会导致大量不必要的双重处理.即使观察值是{{2}}之类的常数,这似乎也是正确的.我在这里误解了什么吗?
| 归档时间: |
|
| 查看次数: |
4390 次 |
| 最近记录: |