具有Angular表达式绑定的无限循环

Pau*_*lor 12 angularjs

我有一个角度应用程序,通过简单的表达式绑定显示控制器方法返回的值:

<div>{{getValue()}}</div>
Run Code Online (Sandbox Code Playgroud)

如果有问题的方法只返回一个值,则该方法被调用两次,这很奇怪:

$scope.getValue = function(){
  return 'some value';
}
Run Code Online (Sandbox Code Playgroud)

但是,如果该方法执行一些异步工作,例如从服务器获取文件,则代码进入无限循环:

$scope.getValueAsync = function(){
  $http.get('myfile.html')
    .success(function (data, status, headers, config) {
      return 'some async value';
    });

  return 'file not found'; // same value returned every time but $digest cycle still loops
}
Run Code Online (Sandbox Code Playgroud)

我是Angular的新手,所以可能错过了一些基本的东西,但有人可以解释一下发生了什么吗?

Plunker

这是一个可以玩http://plnkr.co/7BriYDbdVJvIoIigQcTU的玩家

Ste*_*wie 17

即使你的异步函数每次返回相同的字符串,$ digest循环也会在循环中触发,因为你的函数也使用$ http服务进行ajax调用.

$ http服务$rootScope.$apply() 在请求完成时触发,并且因为$apply触发$摘要周期,它会使您的视图表达式被重新评估,这反过来会导致您的异步函数再次被调用,依此类推......

app.controller('MainCtrl', function($scope, $http) {

  $scope.getValue = function(){
    return 'some value';
  }

  $scope.getValueAsync = function(){
    $http.get('myfile.html')
      .success(function (data, status, headers, config) {
        return 'some async value';
      });

    return 'file not found';
  }
});
Run Code Online (Sandbox Code Playgroud)
<div>{{getValueAsync()}}</div>
Run Code Online (Sandbox Code Playgroud)

故事的道德:如果你在表达式中使用函数,请确保你的函数不会影响它们之外会触发$ digest循环的函数,并确保在给定相同输入的情况下函数总是返回相同的输出.

  • 鉴于AngularJS提供的强大而优雅的功能以及底层JS语言的弱点,我认为必须给予框架每一个功劳并接受其中的一些缺点.无论哪种方式,通过在加载控制器时执行$ http并将结果分配给$ scope变量来规避特定问题是非常容易的. (3认同)