Is there a way to call history.pushState()
without angular going into an infinite digest loop?
I\'m trying to migrate my app from backend routing to fro
I was able to come up with a solution that works with angular 1.2.15.
The gist of it is to add a target
attribute to each link and then use the $location
service to change the location.
Based on the current angular code, anchor tags that have a target attribute are ignored (note that this solution may eventually break).
To do this, ensure this javascript runs before angular:
// prevent angular from taking over link clicks until we have frontend routing
$(document.documentElement).on("click","a",function(event) {
var elem = $(this), target = elem.attr("target");
if(!target) {
elem.attr("target","_self");
setTimeout(function() {
elem.removeAttr("target");
});
}
});
After that, configure your location provider to use html5mode:
angular.module("App", ["App.controllers"]).config([
"$locationProvider", function($locationProvider) {
if (history.pushState) {
$locationProvider.html5Mode(true);
}
}
]);
Now, in your controller, inject the location service and use it normally:
angular.module("App.controllers",[]).controllers("SomeController", ["$scope", "$location", function($scope,$location){
$scope.updateLocation = function() {
if (history.pushState) {
$location.path("/new/path/here");
}
};
}]);
This is what we do in an Angular 1.2.16 app based on this github comment: https://github.com/angular/angular.js/issues/3924#issuecomment-48592773
$location.url(myNewUrl);
$location.replace();
$window.history.pushState(null, 'any', $location.absUrl());
This code is part of a controller. I'm using it to add a query param to the url without wanting to reload the page. It works in our case.
I recently encountered a variation of this problem myself and none of the answers here worked for me in isolation. history.pushState
was defined, but only worked if called from the console. I was able to come up with a solution by consolidating a few of the answers here. Here is the code I used to solve this problem:
// Configure $locationProvider html5Mode
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode({ enabled: true, requireBase: false, rewriteLinks: false });
}]);
// In controller
$window.history.pushState(null, 'Page Title', '/some_new_url');
I'm running Angular 1.5.5.
Use the rewriteLinks option on the $locationProvider html5Mode object:
pageModule.config(function($locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
});
});
Afterwards, you should be able to use the $location service properly, such as:
this.$location.path("/mynewpath");