Do you want to request a feature or report a bug?
Bug
What is the current behavior?
Having a recursive AngularJs 1.5 component with templateUrl throws
[$rootScope:infdig] 10 $digest() iterations reached. Aborting!
While having the template inline works fine. See plnkr for this behavior.
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem via https://plnkr.co or similar (template: http://plnkr.co/edit/tpl:yBpEi4).
http://plnkr.co/edit/gCP6H9EIWa1pEJ0ywp0r?p=preview
Using inline template works fine while templateUrl throws error.
What is the expected behavior?
Having a templateUrl should work just as well as having template in a recursive component. Changing the plnkr to have the template inline instead, no error is thrown.
What is the motivation / use case for changing the behavior?
It鈥檚 inconsistent behavior and doesn鈥檛 seem to work for templateUrl.
Which versions of AngularJS, and which browser / OS are affected by this issue? Did this work in previous versions of AngularJS? Please also test with the latest stable and snapshot (https://code.angularjs.org/snapshot/) versions.
Angular 1.5.11 and later (all browsers).
Other information (e.g. stacktraces, related issues, suggestions how to fix)
Note: This appears to happen in 1.5.X, and not only 1.5.11+.
Before 1.5.x, this will hang the browser with templateUrl, and error out with too much recursion with template. Generally, recursive directives are not really supported out of the box, so I'm not sure how much we can do about this at this point. It sure is awkward that it works with template, but not templateUrl, but also not surprising as templateUrl introduces a lot of asynchronicity.
The issue can be solved with a workaround by increasing the digest iteration limit.
var module = angular.module('bugapp', [], function($rootScopeProvider) {
$rootScopeProvider.digestTtl(15);
});
See a working plunker: http://plnkr.co/edit/WK3o5Ot5sArBDsZEEekA?p=preview
This might work, but it's still going to be problematic when you're level of recursion is dynamic.
But if you do know that you need a max of 15 levels of recursion, this could remove the error.
However, I'm not sure whether or not the application's performance is going to like that.
This has less to do with recursion and more to do with just how the digest cycle in general works.
$templateRequest
uses $evalAsync
internally as an async trampoline, and that means a new iteration of the digest cycle. The problem comes in with ngRepeat
or ngIf
or anything that transcludes based on the value of a watcher, since that introduces another level of async. As a result, you end up going $evalAsync
-> ngRepeat/ngIf
-> $evalAsync
`-> ... which can only occur so many times before you hit the digest cycle error.
You can see this occur yourself by manually unrolling this into 11+ levels of nesting. If you do it without ngIf/ngRepeat
, it works perfectly fine. If you introduce ng-if="true"
into the mix, it blows up.
Most helpful comment
This has less to do with recursion and more to do with just how the digest cycle in general works.
$templateRequest
uses$evalAsync
internally as an async trampoline, and that means a new iteration of the digest cycle. The problem comes in withngRepeat
orngIf
or anything that transcludes based on the value of a watcher, since that introduces another level of async. As a result, you end up going$evalAsync
->ngRepeat/ngIf
->$evalAsync
`-> ... which can only occur so many times before you hit the digest cycle error.You can see this occur yourself by manually unrolling this into 11+ levels of nesting. If you do it without
ngIf/ngRepeat
, it works perfectly fine. If you introduceng-if="true"
into the mix, it blows up.