为什么Angular读取$ scope超过需要?

时间:2014-09-18 08:48:07

标签: angularjs-directive angularjs-scope

我注意到Angular在阅读$ scope属性方面不够保守。当app / controller首次实例化时,通过$ scope公开的模型中定义的每个绑定属性都会被读取两次。当任何属性更改时,将再次读取所有绑定属性。

有人可以解释为什么(或者我做错了什么)?

这里有一些代码可供说明。

我在一个对象上定义了两个属性,这样我就可以在任何时候读取该属性console.log

obj对象

var obj = [];

Object.defineProperty(obj, "a", {
    get: function(){
        console.log("get obj.a: " + this.aVal);
        return this.aVal;
    },
    set: function(val){
        this.aVal = val;
        console.log("set obj.a = " + this.aVal);
    }
});

Object.defineProperty(obj, "b", {
    get: function(){
        console.log("get obj.b: " + this.bVal);
        return this.bVal;
    },
    set: function(val){
        this.bVal = val;
        console.log("set obj.b = " + this.bVal);
    }
});

Angular App:

var app = angular.module("App", [])
.controller("TestCtrl", function($scope){
    $scope.foo = obj;
});

和HTML:

<div ng-app="App">
    <div ng-controller="TestCtrl">
        <input type="text" ng-model="foo.a"></input>
        <input type="text" ng-model="foo.b"></input>
    </div>
</div>

结果

控制台日志如下:

首次运行应用程序时,两个属性都被调用两次:

get obj.a: undefined
get obj.b: undefined
get obj.a: undefined
get obj.b: undefined

为obj.a输入“x”时,将再次读取这两个属性

set obj.a = x
get obj.a: x
get obj.b: undefined

2 个答案:

答案 0 :(得分:1)

Angular处理双向绑定。它的方式是通过脏检查。它会检查摘要顶部的任何监视属性,然后检查摘要的底部(两次)。然后比较这些值以查看是否有任何变化。这是它知道是否需要重新绑定UI的方式。请阅读this article以供参考。

摘要周期在范围内调用$apply的任何时候运行。 Angular经常这样做(在它自己的指令中,例如ng-click)。

答案 1 :(得分:0)

尝试使用firebug捕获堆栈,但它似乎(我知道它的角度)来自$ watch实现 - 它必须首先评估对象的当前散列以启动&#34; listen&#34;它的变化。因此,首先阅读对象是内部检查,其次是查看。不确定,但它必须两次读取对象以实现$ watch magic。