2013-02-23 47 views
5

我刚刚发现了这个有趣的明显不一致什么是允许在角表达式:为什么赋值不总是在Angular表达式中工作?

  1. 有可能在表达
  2. 这打破如果转让涉及从ngRepeat
  3. 一个局部变量进行赋值这可以通过在表达使用在控制器的替代分配所限定的设定器来克服

See Plunker

docs on expressions似乎只是明确地禁止表达式中的控制流,而且我没有看到任何提及的上述行为。

我想这件事可能是一个更好的使用setter的设计模式,但是没有人知道表达式中可能有更多明确的参考吗?

也许这样会更好,如果Angular单方面禁止转让他们。 (相关的不一致是,似乎有可能在i = i + 1的表达式中增加,但是i + = 1没有增加)。

回答

11

这是一个已知问题,在指令中进行了作用域。您可以阅读文章The Nuances of Scope Prototypal Inheritance以了解更多关于角度js中的scoping的信息。

从孩子/ 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:
使用父范围
二传手

  1. $scope.setSelectedNumber = function(num){ $scope.selectedNumber = num}
  2. 更改创建父范围setter方法点击事件setSelectedNumber(number) (这已经是所采用的方法)

更新:
作为建议由Anders Ekdahl,建议使用基于对象(解决方案1)的解决方案。

+1

您应该使用一个对象作为模型,而不是通过$ parent访问父范围。访问$父导致脆弱的代码,因为如果要在两者之间添加另一个范围,它将停止工作。 – 2013-02-23 07:13:33

+0

@AndersEkdahl你是对的,我只是给出了可用的选项作为答案,指针文章解释了用例和问题 – 2013-02-23 07:21:41

+0

太棒了!感谢你及时的答复!这是完全合理的。仅供参考,实际使用情况是基于预览“色板”阵列在页面编辑器中动态选择页面背景。被设置的值被称为'selectedClass',但它是一个字符串,所以我猜它仍然是一个原始类型,同样的问题也适用。尽管看到你的解决方案真是太棒了,你认为控制器中的setter会是更好的设计吗? – bellkev 2013-02-23 07:23:12

相关问题