2
votes

I'm working on integrating Angular into a legacy app. This requires updating the route from outside of a controller, because the old app has a LoadPage script outside of Angular that must execute a few functions before the browser's URL is set.

To change the Angular route, I do something along these lines:

var $injector = angular.element($("#angularApp")).injector();
var $location = $injector.get('$location');
var scope = angular.element($("#angularApp")).scope();
scope.$apply(function () {
    $location.path("/newurl");
});

This works fine if the user is clicking around in the application, but it fails to change the template when the back button is used (even though the LoadPage script runs again and my logs indicate that it did run the code above). Also, in a few cases, clicking a link once the back button has been used will give me the dreaded digest error:

Uncaught Error: 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [["fn: function (){var a=d.url(),b=h.$$replace;if(!l||a!=h.absUrl())l++,c.$evalAsync(function(){c.$broadcast(\"$locationChangeStart\",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),i(a))});h.$$replace=!1;return l}; newVal: 18; oldVal: 17"],["fn: function (){var a=d.url(),b=h.$$replace;if(!l||a!=h.absUrl())l++,c.$evalAsync(function(){c.$broadcast(\"$locationChangeStart\",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),i(a))});h.$$replace=!1;return l}; newVal: 19; oldVal: 18"],["fn: function (){var a=d.url(),b=h.$$replace;if(!l||a!=h.absUrl())l++,c.$evalAsync(function(){c.$broadcast(\"$locationChangeStart\",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),i(a))});h.$$replace=!1;return l}; newVal: 20; oldVal: 19"],["fn: function (){var a=d.url(),b=h.$$replace;if(!l||a!=h.absUrl())l++,c.$evalAsync(function(){c.$broadcast(\"$locationChangeStart\",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),i(a))});h.$$replace=!1;return l}; newVal: 21; oldVal: 20"],["fn: function (){var a=d.url(),b=h.$$replace;if(!l||a!=h.absUrl())l++,c.$evalAsync(function(){c.$broadcast(\"$locationChangeStart\",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),i(a))});h.$$replace=!1;return l}; newVal: 22; oldVal: 21"]]

Is there a way to change the route outside of Angular and be sure that Angular updates ng-view properly? Any ideas about the digest error above?

UPDATE: With a watch on locationChangeSuccess, I've narrowed the problem down to the fact that $apply is not always submitting the changes to Angular -- the code to change it definitely runs, but the Angular location is not updated in the scope. $apply only begins failing in this manner on location changes prompted by the Back button.

1
Maybe using a not-minified version of Angular.js would help you debugging...Florent
I tried that, but it didn't say much more. Just a series of ["fn: $locationWatch; newVal: 25; oldVal: 24"], ["fn: $locationWatch; newVal: 26; oldVal: 25"], et cetera. Angular can't seem to establish stability, but I'm not sure why it would only happen once the back button has been used (and only then when the user navigates to the page they just backed out of). I was hoping someone would know of some "gotchas" on that front.Jennifer Gilbert

1 Answers

1
votes

Based on your update:

... Angular location is not updated in the scope

I had similar problem with that in my application and solved by calling $apply from $rootScope. Try:

var rootScope = $injector.get('$rootScope');
rootScope.$apply(function () {
    $location.path("/newurl");
});