【问题标题】:Angular Infinite $digest LoopAngular 无限 $digest 循环
【发布时间】:2014-07-06 02:49:37
【问题描述】:

我正在开发一个网站,您可以在其中搜索食物,看看它是水果还是蔬菜,或者两者都不是(因为我很无聊)。我决定使用 Angular,尽管我对它很陌生。 我开始收到此错误:$rootScope:infdig Infinite $digest Loop

这可能是也可能不是确切的措辞或错误,因为页面滞后太多,我无法打开 Javascript 控制台。

这是我的结果视图控制器:

app.controller('resultController', ['$scope', '$routeParams', '$http',
    function($scope, $routeParams, $http) {
        $scope.result = $routeParams.query;

        $scope.whatIsIt = function() {
            $http.get('json/foods.json').success(function(data) {
                var lists = JSON.parse(data);
                var itIsA = 'uuggghhhhh';

                if (lists['fruit'].contains($scope.result)) {
                    itIsA = 'fruit';
                } else if (lists['vegetable'].contains($scope.result)) {
                    itIsA = 'vegetable';
                }
            });
        }
    }]);

这是我的应用模块:

var app = angular.module('fruitOrNot', [
    'ngRoute'
]);

app.config(['$routeProvider' ,
    function($routeProvider) {
        $routeProvider.when('/', {
            templateUrl: 'layouts/fruit-search.html',
            controller: 'searchController'
        }).when('/:query', {
            templateUrl: 'layouts/result.html',
            controller: 'resultController'
        });
    }]);

这是 layouts/result.html:

<h1>{{ result }}</h1>
<p>{{ result }} is a {{ whatIsIt() }}</p>

所以我想知道是什么导致了$digest 循环错误,或者如何找出原因,因为我无法使用控制台。谢谢!

整个项目在 Github 上也是 here。

【问题讨论】:

  • 创建一个plnkr.co
  • 关于风格的说明——你应该将你的 http 请求分离到一个服务中。它们不应该在控制器中。
  • 好的,谢谢,我会这样做的。

标签: javascript angularjs infinite-loop


【解决方案1】:

您遇到的问题是您在范围上设置了一个字段,该字段隐式调用$digest 并再次布置模板。但是,布局模板再次发出 http 请求,然后更改范围,调用 $digest。这就是无限循环。

您可以通过确保在模板布局期间永远不会触发 http 请求来避免这种情况。

实现您的应用程序的更正确的方法是将您的 GET 请求提取到适当的服务中,然后将您的服务注入控制器。

然后在控制器中进行服务调用,如下所示:

app.controller('resultController', ['$scope', '$routeParams', 'whatsitService',
    function($scope, $routeParams, $http) {
        $scope.result = $routeParams.query;
        whatsitService.doit().then(function(result) {
            $scope.whatsit = result;
        }
    })
;

您的模板将如下所示:

<h1>{{ result }}</h1>
<p>{{ result }} is a {{ whatsit }}</p>

【讨论】:

  • 我更新了我的代码以使用服务,但我收到此错误:` 未知提供者:whatIsItProvider
  • 在您的示例中,这行:function($scope, $routeParams, $http) { 不应该是:function($scope, $routeParams, whatsisService) { 吗?
【解决方案2】:

问题是您尝试调用函数并直接发布返回值,而您尝试返回的值超出范围。您需要将该值放在范围内。

代码sn-p:

app.controller('resultController', ['$scope', '$routeParams', '$http',
function($scope, $routeParams, $http) {
    $scope.result = $routeParams.query;
    $scope.itIsA = "";
    $scope.whatIsIt = function() {
        $http.get('json/foods.json').success(function(data) {
            var lists = JSON.parse(data);
            var itIsA = 'uuggghhhhh';

            if (lists['fruit'].contains($scope.result)) {
                $scope.itIsA = 'fruit';
            } else if (lists['vegetable'].contains($scope.result)) {
                $scope.itIsA = 'vegetable';
            }               

        });
    }
}]);

在 HTML 模板中:

p>{{ result }} is a {{itIsA}}</p>

【讨论】:

    【解决方案3】:

    如果您已将表达式绑定到它,则在以下情况下可能会发生无限 $digest 循环:{{events()}}

    和

    $scope.events = function() { return Recording.getEvents(); }

    但不是在以下情况下。即使你绑定了{{events}}

    $scope.events = Recording.getEvents();

    原因在于第一个角度假设值在每个摘要循环中都在变化并且它不断更新它。在第二个中,它只是等待承诺。

    【讨论】:

      【解决方案4】:

      这是因为在您的角度表达式“{{ whatIsIt() }}”中 “{{ result }} is a {{ whatIsIt() }}”您正在调用一个函数,该函数每次调用都返回不同的值,从而导致一个新的摘要循环,进而调用该函数。

      我认为您应该将whatIsIt() 的结果绑定到一个值,然后在模板中使用该值。看看这个https://docs.angularjs.org/error/$rootScope/infdig

      【讨论】:

      • 我们宁愿让您测试并按照您的想法工作。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多