6

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

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

见 Plunker

关于表达式的文档似乎只是明确禁止表达式中的控制流,而且我没有看到任何提及上述行为的内容。

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

如果 Angular 单方面禁止在它们中分配可能会更好。(一个相关的不一致是,似乎可以在表达式中增加 i = i+1 但不能增加 i+=1...)

4

1 回答 1

12

这是指令中范围界定的一个已知问题。您可以阅读文章The Nuances of Scope Prototypal Inheritance以了解有关scopingin angular js 的更多信息。

来自子/转入范围的任何原始值分配都将创建一个新的实例值,而不是更改父范围的值

在您的情况下,您正在使用原始值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. 将点击事件更改为setSelectedNumber(number) (这是已经使用的方法)

更新:
正如 Anders Ekdahl 所建议的,建议使用基于对象(解决方案 1)的解决方案。

于 2013-02-23T06:36:33.573 回答