在指令中分配$ watch之外的隔离范围对象会产生不可预测的行为

时间:2016-05-19 12:25:17

标签: javascript angularjs angularjs-directive angularjs-scope

在工作中,我们使用AngularJS作为我们的前端。我们是一个大规模形式驱动的应用程序,需要大量可重用的组件。

我们将这些可重用组件建模为具有隔离范围的指令。这对我们来说很有意义,因为有多种情况我们最终会在页面上使用相同的指令2次。

执行此操作时,我似乎遇到了与$watch函数外部设置隔离范围对象有关的问题。

情景:

  • 每个指令都有自己的隔离范围
  • 每个指令通过load-id属性
  • 接收其输入
  • load-id属性上有$watch并对更改作出反应。
  • 每个指令对通过load-id接收的值执行操作(在本例中为简单的增量),并将结果绑定到result属性,以便父范围可以访问它。
  • 此增量操作在内部increment调用$watch方法执行。

用法:

<div foo-bar load-id="{{loadId1}}" result="res1"></div>
<pre>{{ res1 }}</pre>

<div foo-bar load-id="{{loadId2}}" result="res2"></div>
<pre>{{ res2 }}</pre>

<div foo-bar load-id="{{loadId3}}" result="res3"></div>
<pre>{{ res3 }}</pre>

期望(相对于上述用法):

res1res2res3loadId1loadId2loadId3分别增加1。

现实

最后一个指令结果(在我们的例子中是res3)是唯一绑定的对象。 <{1}}和res1未定义。

以下是重现问题的最简单方法:http://jsbin.com/henixicubo/1/edit?html,js,output

其他研究

经过一番挖掘,我发现如果我们使用res2功能并直接绑定到increment scope.result,事情很好。

以上是与上面相同的示例,但使用$watch函数:http://jsbin.com/figizecadi/1/edit?html,js,output完全按预期工作。

这对我来说真是令人费解。我在这里做错了吗?我对范围的理解完全重击?

1 个答案:

答案 0 :(得分:1)

问题是你的增量函数是一个全局函数(它被分配给窗口对象),JavaScript使用函数范围(http://www.w3schools.com/js/js_scope.asp),如果你定义你的函数(var )它会工作。我修改了您的代码,请尝试以下代码:http://jsbin.com/lohizibure/edit?html,js,output