为什么 AngularJS 在每个摘要循环中执行函数?
Why does AngularJS execute function on every digest loop?
我来自 Knockout,我正在尝试了解 Angular 如何更新范围。我有点困惑为什么在作用域上定义的函数(例如 $scope.doStuff = function()
)在每次作用域刷新时都会执行。
Plnkr link: http://plnkr.co/edit/YnvOELGkRbHOovAWPIpF?p=preview
例如:
HTML
<div ng-controller="one">
<input type="text" ng-model="a">
{{b()}}
</div>
JS
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.a = 'one';
$scope.b = function () {
console.log('b has executed');
}
}])
因此,每当 $scope.a
的输入表单字段中发生事件时,都会执行函数 $scope.b
。为什么会这样?那个函数没有依赖,一直刷新好像效率不高
如果我在相同的结构中添加另一个控制器,如下所示:
HTML
<div ng-controller="one">
<input type="text" ng-model="a">
{{b()}}
</div>
<div ng-controller="two">
<input type="text" ng-model="x">
{{y()}}
</div>
JS
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.a = 'one';
$scope.b = function () {
console.log('b has executed');
}
}])
.controller('two', ['$scope', function ($scope) {
$scope.x = 'two';
$scope.y = function () {
console.log('y has executed');
}
}])
每次我在控制器 one
中更新 $scope.a
时,输出是:
b has executed
y has executed
为什么控制器 two
正在执行 $scope.y
?我认为创建一个新的控制器会创建一个新的子范围。是因为子作用域被 link 编辑到父作用域了吗?
更有趣的是,如果我在控制器 two
中更新 $scope.x
那么输出是:
b has executed
y has executed
b has executed <-- a second time... what?
为什么函数 $scope.b
被执行了第二次?
那么为什么 Angular 中的函数会在每次作用域刷新时执行?
仅仅是因为不可能知道一个函数的所有依赖项是什么。假设您的函数 b
(在控制器 one
上)是这样的:
$scope.b = function () {
console.log('b has executed');
another_func($scope);
}
函数 another_func
的定义是这样的:
function another_func (obj) {
obj.a = 'something';
return obj.a;
}
您如何以编程方式知道函数 $scope.b
将调用一个函数,该函数将调用另一个函数来获取依赖于 $scope.a
的值?
Angular 使用所谓的脏检查。为了保持视图和控制器之间的绑定,必须验证绑定到函数的任何变量。
像您演示的那样使用通常不是一个好主意,并且会影响中型到大型应用程序的性能。
建议使用固定变量绑定到视图并在需要时更改,这将带来更高的整体性能并且只重新渲染已更改的部分。
一般来说,您不会 'call' 视图中的函数,但有时这是唯一的方法,如果在 ng-repeat 中使用动态数据,那么我会将该数据放入 object/array 和 return object/array,那么即使 angular 将继续在其摘要循环中调用该函数,如果不更改,它也不会 'update' 视图。
这里我是这样认为的,每次页面加载时,angular js 都会启动该函数,这意味着每次页面加载时都会执行,所以不要直接调用,使用 ng-change 调用它.
<div ng-controller="one">
<input type="text" ng-model="a" ng-change=b()>
</div>
<div ng-controller="two">
<input type="text" ng-model="x" ng-change=y()>
</div>
并且在控制器中,您可以按如下方式将该功能分配给所需的 ng-model,
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.b = function () {
$scope.a = 'one';
console.log('b has executed');
}
}])
.controller('two', ['$scope', function ($scope) {
$scope.y = function () {
$scope.x = 'two';
console.log('y has executed');
}
}])
否则您也可以通过分配给 ng-model return 函数值给您的 ng-model,它会给出您的正确答案,而不是每次都调用。
我来自 Knockout,我正在尝试了解 Angular 如何更新范围。我有点困惑为什么在作用域上定义的函数(例如 $scope.doStuff = function()
)在每次作用域刷新时都会执行。
Plnkr link: http://plnkr.co/edit/YnvOELGkRbHOovAWPIpF?p=preview
例如:
HTML
<div ng-controller="one">
<input type="text" ng-model="a">
{{b()}}
</div>
JS
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.a = 'one';
$scope.b = function () {
console.log('b has executed');
}
}])
因此,每当 $scope.a
的输入表单字段中发生事件时,都会执行函数 $scope.b
。为什么会这样?那个函数没有依赖,一直刷新好像效率不高
如果我在相同的结构中添加另一个控制器,如下所示:
HTML
<div ng-controller="one">
<input type="text" ng-model="a">
{{b()}}
</div>
<div ng-controller="two">
<input type="text" ng-model="x">
{{y()}}
</div>
JS
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.a = 'one';
$scope.b = function () {
console.log('b has executed');
}
}])
.controller('two', ['$scope', function ($scope) {
$scope.x = 'two';
$scope.y = function () {
console.log('y has executed');
}
}])
每次我在控制器 one
中更新 $scope.a
时,输出是:
b has executed
y has executed
为什么控制器 two
正在执行 $scope.y
?我认为创建一个新的控制器会创建一个新的子范围。是因为子作用域被 link 编辑到父作用域了吗?
更有趣的是,如果我在控制器 two
中更新 $scope.x
那么输出是:
b has executed
y has executed
b has executed <-- a second time... what?
为什么函数 $scope.b
被执行了第二次?
那么为什么 Angular 中的函数会在每次作用域刷新时执行?
仅仅是因为不可能知道一个函数的所有依赖项是什么。假设您的函数 b
(在控制器 one
上)是这样的:
$scope.b = function () {
console.log('b has executed');
another_func($scope);
}
函数 another_func
的定义是这样的:
function another_func (obj) {
obj.a = 'something';
return obj.a;
}
您如何以编程方式知道函数 $scope.b
将调用一个函数,该函数将调用另一个函数来获取依赖于 $scope.a
的值?
Angular 使用所谓的脏检查。为了保持视图和控制器之间的绑定,必须验证绑定到函数的任何变量。
像您演示的那样使用通常不是一个好主意,并且会影响中型到大型应用程序的性能。
建议使用固定变量绑定到视图并在需要时更改,这将带来更高的整体性能并且只重新渲染已更改的部分。
一般来说,您不会 'call' 视图中的函数,但有时这是唯一的方法,如果在 ng-repeat 中使用动态数据,那么我会将该数据放入 object/array 和 return object/array,那么即使 angular 将继续在其摘要循环中调用该函数,如果不更改,它也不会 'update' 视图。
这里我是这样认为的,每次页面加载时,angular js 都会启动该函数,这意味着每次页面加载时都会执行,所以不要直接调用,使用 ng-change 调用它.
<div ng-controller="one">
<input type="text" ng-model="a" ng-change=b()>
</div>
<div ng-controller="two">
<input type="text" ng-model="x" ng-change=y()>
</div>
并且在控制器中,您可以按如下方式将该功能分配给所需的 ng-model,
angular.module('test', [])
.controller('one', ['$scope', function ($scope) {
$scope.b = function () {
$scope.a = 'one';
console.log('b has executed');
}
}])
.controller('two', ['$scope', function ($scope) {
$scope.y = function () {
$scope.x = 'two';
console.log('y has executed');
}
}])
否则您也可以通过分配给 ng-model return 函数值给您的 ng-model,它会给出您的正确答案,而不是每次都调用。