javascript Angular 无限 $digest 循环
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24592283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular Infinite $digest Loop
提问by Addison
I am working on a site where you can search a food, and see if its a fruit, a vegetable, or neither (because I'm bored). I decided to use Angular, even though I'm pretty new to it. I started getting this error: $rootScope:infdig Infinite $digest Loop
我正在一个网站上工作,您可以在其中搜索食物,看看它是水果、蔬菜还是两者都不是(因为我很无聊)。我决定使用 Angular,尽管我对它很陌生。我开始收到这个错误:$rootScope:infdig Infinite $digest Loop
That's may or may not be the exact phrasing or the error, because the page lags out so much, I can't open the Javascript console.
这可能是也可能不是确切的措辞或错误,因为页面滞后太多,我无法打开 Javascript 控制台。
This my result view controller:
这是我的结果视图控制器:
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';
}
});
}
}]);
Heres my app module:
这是我的应用程序模块:
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'
});
}]);
And here is layouts/result.html:
这是 layouts/result.html:
<h1>{{ result }}</h1>
<p>{{ result }} is a {{ whatIsIt() }}</p>
So I am wondering what could be causing that $digest
loop error, or how to find out, because I can't use the console. Thanks!
所以我想知道是什么导致了该$digest
循环错误,或者如何找出原因,因为我无法使用控制台。谢谢!
The whole project is hereon Github as well.
整个项目也在Github 上。
回答by Andrew Eisenberg
The problem that you were having was that you were setting a field on the scope, which implicitly calls $digest
and lays out the template again. But, laying out the template makes the http request again, and then changes the scope, which calls $digest. And that is the infinite loop.
您遇到的问题是您在作用域上设置了一个字段,该字段会$digest
再次隐式调用和布局模板。但是,布局模板会再次发出 http 请求,然后更改调用 $digest 的范围。这就是无限循环。
You can avoid this by ensuring that the http request never gets triggered during a layout of the template.
您可以通过确保在模板布局期间永远不会触发 http 请求来避免这种情况。
A more angular correct way of implementing your app would be to extract your GET request into a proper service and then injecting your service into the controller.
实现您的应用程序的一种更有角度的正确方法是将您的 GET 请求提取到适当的服务中,然后将您的服务注入到控制器中。
Then in the controller, you make the service call, like this:
然后在控制器中,您进行服务调用,如下所示:
app.controller('resultController', ['$scope', '$routeParams', 'whatsitService',
function($scope, $routeParams, $http) {
$scope.result = $routeParams.query;
whatsitService.doit().then(function(result) {
$scope.whatsit = result;
}
})
;
Your template would look like this:
您的模板如下所示:
<h1>{{ result }}</h1>
<p>{{ result }} is a {{ whatsit }}</p>
回答by V31
The problem is you trying to call a function and publish the return value directly and the value that you are trying to return is out of scope. You need to put that value in scope.
问题是您尝试调用函数并直接发布返回值,而您尝试返回的值超出范围。您需要将该值放入范围内。
Code snippet:
代码片段:
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';
}
});
}
}]);
and in the HTML Template:
并在 HTML 模板中:
p>{{ result }} is a {{itIsA}}</p>
回答by Siamak Rahimi
Infinite $digest Loop can happen in this below case if you have bound an expression to it like : {{events()}}
如果您已将表达式绑定到它,则在以下情况下可能会发生无限 $digest 循环: {{events()}}
and
和
$scope.events = function() {
return Recording.getEvents();
}
$scope.events = function() {
return Recording.getEvents();
}
But not in the below case. even if you have bound {{events}}
但不是在下面的情况下。即使你已经绑定{{events}}
$scope.events = Recording.getEvents();
$scope.events = Recording.getEvents();
The reason is in the first angular suppose the value is changing in every digest loop and it keeps updating it. In second one it simply wait for the promise.
原因是在第一个角度假设值在每个摘要循环中都在变化并且它不断更新它。在第二个中,它只是等待承诺。
回答by Ebi Igweze
It is happening because of in your angular expression '{{ whatIsIt() }}
' in
"{{ result }} is a {{ whatIsIt() }}
" you are calling a function that returns a different value each time invoke thus causing a new digest cycle which in turn invokes the function.
之所以发生这种情况,是因为{{ whatIsIt() }}
在“ {{ result }} is a {{ whatIsIt() }}
”中的角度表达式“ ”中,您正在调用一个函数,该函数每次调用都会返回不同的值,从而导致新的摘要循环,该循环又会调用该函数。
I think you should bind the result of whatIsIt()
to a value and then use that value in template. check this out https://docs.angularjs.org/error/$rootScope/infdig
我认为您应该将 的结果绑定whatIsIt()
到一个值,然后在模板中使用该值。看看这个https://docs.angularjs.org/error/$rootScope/infdig