为什么赋值并不总是在Angular表达式中有效?

bel*_*kev 5 javascript angularjs

我刚刚在Angular表达式中允许的内容中发现了这个有趣的明显不一致:

  1. 可以在表达式中执行赋值
  2. 如果赋值涉及ngRepeat中的局部变量,则会中断
  3. 这可以通过使用控制器中定义的setter而不是表达式中的赋值来克服

见Plunker

关于表达式文档似乎只是明确地禁止表达式中的控制流,我没有看到上面提到的那种行为.

我想从这里得到的结论是,无论如何使用setter可能是一个更好的设计模式,但有没有人知道关于表达式中可能的更明确的参考?

如果Angular单方面禁止在其中进行转让,那也许会更好.(相关的不一致是,似乎可以在i = i + 1的表达式中递增,但不能用i + = 1 ......)

Aru*_*hny 11

这是指令中作用域的已知问题.您可以阅读文章The Scope of Scope Prototypal Inheritance来了解有关scoping角度js的更多信息.

来自子/ transcluded范围的任何原始值赋值将创建新的实例值,而不是更改父范围值

在您的情况下,您正在使用原始值selectedNumber.

有两种建议的方法可以解决它

解决方案1
使用对象而不是原始值.

  1. 将selectedNumber更改为对象 scope.selectedNumber = { num : 1 };
  2. 将显示更改为 <h2>{{ selectedNumber.num }}</h2>
  3. 将点击处理程序更改ng-repeatng-click="selectedNumber.num = number"

演示:Plunker

解决方案2:
使用$parent范围参考

  1. 将点击处理程序更改ng-repeatng-click="$parent.selectedNumber = number"

演示:Plunker

解决方案3:
在父作用域中使用setter

  1. 在父作用域中创建一个setter方法 $scope.setSelectedNumber = function(num){ $scope.selectedNumber = num}
  2. 将click事件更改为setSelectedNumber(number) (这是已使用的方法)

更新:
根据Anders Ekdahl的建议,建议使用基于对象(解决方案1)的解决方案.