为什么AngularJS在每个摘要循环上都执行函数

Why does AngularJS execute function on every digest loop?

本文关键字:循环 执行 函数 AngularJS 为什么      更新时间:2023-09-26

我来自Knockout,我正在努力了解Angular是如何更新范围的。我有点困惑,为什么在每次刷新作用域时都会执行作用域上定义的函数(例如$scope.doStuff = function())。

Plnkr链接: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?我认为创建一个新的控制器会创建一个子作用域。是因为子作用域链接到父作用域吗?

更有趣的是,如果我在控制器two中更新$scope.x,那么输出是:

b has executed
y has executed
b has executed <-- a second time... what?

为什么函数$scope.b会被第二次执行?

那么,为什么Angular中的函数会在每次范围刷新时执行呢?

Angular使用所谓的脏检查。为了维护视图和控制器之间的绑定,必须验证绑定到函数的任何变量。

像您演示的那样使用通常是个坏主意,并且可能影响中大型应用程序的性能。

建议使用固定变量绑定到视图,并在需要时进行更改,这将提高整体性能,并且只会重新渲染已更改的部分。

通常情况下,你不会从视图中"调用"函数,但有时这是唯一的方法。如果在ng重复中使用动态数据,那么我会将数据放入对象/数组中并返回该对象/数组,然后即使angular在其摘要周期中继续调用函数,如果不更改,也不会"更新"视图。

这里我认为是这样的,每次页面加载时,angular js都会启动该函数,这意味着每次页面加载都会执行,所以不要直接调用,而是使用ng更改来调用它。

<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模型,如下所示,

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模型来将函数值返回给ng模型,它将给出正确的答案,而不是每次调用。

因为不可能知道函数的所有依赖项是什么。假设你的函数b(在控制器one上)是这样的:

  $scope.b = function () {
    console.log('b has executed');
    another_func($scope);
  }

函数CCD_ 13的定义如下:

function another_func (obj) { 
    obj.a = 'something';
    return obj.a;
}

如何通过编程知道函数$scope.b将调用一个函数,该函数将调用另一个函数以获得依赖于$scope.a的值?