12

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

<div>{{getValue()}}</div>

如果所讨论的方法只返回一个值,则该方法会被调用两次,这很奇怪:

$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'; // same value returned every time but $digest cycle still loops
}

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

普朗克

这是一个与http://plnkr.co/7BriYDbdVJvIoIigQcTU一起玩的 plunker

4

2 回答 2

17

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

$http 服务$rootScope.$apply() 在请求完成时触发,并且由于$apply触发 $digest 循环,它使您的视图表达式被重新评估,这反过来导致您的异步函数被再次调用,等等......

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';
  }
});
<div>{{getValueAsync()}}</div>

故事的寓意:如果您在表达式中使用函数,请确保您的函数不会影响它们之外会触发 $digest 循环的内容,并确保您的函数在给定相同输入的情况下始终返回相同的输出。

于 2013-07-04T10:59:09.260 回答
0

我遇到了和你一样的问题,为了解决这个问题我们可以缓存函数的结果。为此,我更喜欢使用 Lo-Dash 的 memoize 功能。我创建了一个演示来向您展示我是如何解决这个问题的。The following link contains the demo:http://plnkr.co/edit/KBmk4J2ZCt0SsmZlnKZi?p=preview

于 2017-11-13T11:26:14.827 回答