我正在使用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>© <b>{{author}}</b>, {{year}}</footer>
</div>
所以问题是:在我希望每次值都不同的情况下,有没有办法避免这种错误?
答案 0 :(得分:2)
由于如何评估插值绑定{{ }}
,因此无法工作。
插值绑定不会被评估一次。它们每$digest
个周期进行一次评估,以确定它们的值是否需要更新,这是角度双向绑定如何工作的基石。不幸的是,在插值绑定中执行的函数会导致另一个$digest
周期触发,以确定函数调用是否进行了任何需要更新其他绑定的更改。
在这种情况下,这会产生一些问题,因为$digest
永远不会稳定。每次调用$digest
都会生成一个新的randomJoke
,这会导致$digest
再次触发。如果您查看infdig
错误,实际上可以看到Watchers fired in the last 5 iterations
在oldVal
和newVal
中显示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