为什么 Angular 读取的 $scope 超出了需要? [英] Why does Angular read $scope more than needed?

查看:40
本文介绍了为什么 Angular 读取的 $scope 超出了需要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到 Angular 在读取 $scope 属性时不太保守.当应用程序/控制器第一次实例化时,通过 $scope 公开的模型中定义的每个绑定属性都会被读取两次.当任何属性发生变化时,所有绑定的属性都会再次读取.

有人能解释一下原因吗(或者我做错了什么)?

这里有一些代码来说明.

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

obj 对象

var obj = [];Object.defineProperty(obj, "a", {得到:函数(){console.log("获取 obj.a:" + this.aVal);返回 this.aVal;},设置:函数(val){this.aVal = val;console.log("set obj.a = " + this.aVal);}});Object.defineProperty(obj, "b", {得到:函数(){console.log("get obj.b:" + this.bVal);返回 this.bVal;},设置:函数(val){this.bVal = val;console.log("set obj.b = " + this.bVal);}});

Angular 应用:

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

和 HTML:

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

结果

控制台日志如下:

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

get obj.a: 未定义获取 obj.b:未定义获取 obj.a:未定义获取 obj.b:未定义

当为 obj.a 输入x"时,两个属性都会被再次读取

set obj.a = x得到 obj.a: x获取 obj.b:未定义

解决方案

Angular 处理双向绑定.它的方式是通过脏检查.它检查摘要顶部和摘要底部的任何监视属性(两次).然后比较这些值以查看是否有任何更改.这是它知道是否需要重新绑定 UI 的方式.阅读这篇文章以供参考.

摘要循环在作用域上调用 $apply 的任何时候运行.Angular 经常这样做(在它自己的指令中,例如 ng-click).

I noticed that Angular is less-than-conservative when it comes to reading $scope properties. When the app/controller first instantiate, each bound property defined in the model exposed via $scope is read twice. When any property changes, all the bound properties are read again.

Can someone explain why (or am I doing something incorrectly)?

Here's some code to illustrate.

I defined two properties on an object so that I could console.log anytime the property is read.

The obj Object

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);
    }
});

The Angular App:

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

and 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>

The result

The console log is as follows:

when first running the app both properties are called twice each:

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

when entering "x" for obj.a, both properties are read again

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

解决方案

Angular handles two-way binding. The way it does it is through dirty checking. It checks any watched property at the top of the digest and then at the bottom of the digest (twice). It then compares the values to see if anything changed. This is the way it knows whether it needs to rebind the UI. Read this article for reference.

The digest cycle runs anytime there is an $apply called on the scope. Angular does this often (inside its own directives, e.g. ng-click).

这篇关于为什么 Angular 读取的 $scope 超出了需要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆