如何预防"错误:$ rootScope:infdig"当每次不同的值是预期的行为

时间:2016-01-16 13:00:54

标签: javascript angularjs

我正在使用AngularJS(使用Aria,Animate,Material,Messages,Sanitize和Route)处理页面,每个工作正常但我有点问题。 Angular喜欢扔"错误:$ rootScope:infdig"当每次刷新页面时,函数返回的值都不同,但这就是我写的一个函数正是要做的。

代码:

<script>

    angular.module('tht', ['ngMaterial', 'ngSanitize', 'ngMessages', 'ngAnimate', 'ngAria'])

    .controller('MainController', ['$scope', '$rootScope', function($scope, $rootScope) {
        $rootScope.version = '0.1';
        $rootScope.name = 'tht';
        $rootScope.author = 'D3add3d';
        $rootScope.year = '2016';
        $scope.jokes = ["We ate a bunch of doritos and now the page is blank...", 
                        "Sometimes it just looks like this...", 
                        "Kappa, Kappa, Kappa, Kappa...", 
                        "This text changes every time I refresh the page, weird huh o_O", 
                        "We are out of doritos :-/", 
                        "Powered by your satisfaction... wait", 
                        "Instead of working on this page, I'm writing these jokes #procrastination", 
                        "Have a hug or two *hugs*", 
                        "<3", "<3~~~", 
                        "This joke is so simple... return array[Math.floor(Math.random() * array.length)];", 
                        "Go eat some chocolate, it helps ;)", 
                        "I love you all :-* <3", "[~~HUG~~]", 
                        "[?BUG?]"];
        $scope.randomJoke = function() {
            return $scope.jokes[Math.floor(Math.random() * $scope.jokes.length)]; //function that returns different value (almost) every time it is called
        }
    }]);

</script>

HTML:

<div ng-controller="MainController" ng-hide>

    <header>Hello, this is <b>{{name}}</b>, version <b>{{version}}</b>
    <article><br>{{randomJoke()}}</article> <!-- THIS IS WHAT CAUSES THE ERROR -->
    </header>
    <footer>&copy; <b>{{author}}</b>, {{year}}</footer>

</div>

所以问题是:在我希望每次值都不同的情况下,有没有办法避免这种错误?

2 个答案:

答案 0 :(得分:2)

由于如何评估插值绑定{{ }},因此无法工作。

每次重新加载时,

插值绑定不会被评估一次。它们每$digest个周期进行一次评估,以确定它们的值是否需要更新,这是角度双向绑定如何工作的基石。不幸的是,在插值绑定中执行的函数会导致另一个$digest周期触发,以确定函数调用是否进行了任何需要更新其他绑定的更改。

在这种情况下,这会产生一些问题,因为$digest永远不会稳定。每次调用$digest都会生成一个新的randomJoke,这会导致$digest再次触发。如果您查看infdig错误,实际上可以看到Watchers fired in the last 5 iterationsoldValnewVal中显示5个不同的笑话。

infdig错误实际上是故障保护,角度在10次迭代后停止摘要,以确保您不会完全锁定浏览器。实际上,可以以这种方式使用代码,但应用程序会因此导致性能下降。

更好的方法是绑定到分配给函数调用结果的变量,该变量在控制器初始化期间计算一次。

答案 1 :(得分:0)

看起来绑定到函数是导致无限摘要周期的罪魁祸首:Explanantion

要解决此问题,请改为绑定到变量:<article><br>{{randomJoke}}</article>

在控制器中,而不是randomJoke()函数,为变量分配一个随机生成的笑话:

$scope.randomJoke = $scope.jokes[Math.floor(Math.random() * $scope.jokes.length)];

Plunker:https://plnkr.co/edit/UPc3CGhPgyfAWafI92b4?p=preview