JonasR JonasR - 1 month ago 8
AngularJS Question

ngClick with window.location.href lands redirect twice

My mobile first application needs clickable table rows for navigation, which it solves through

<tr ng-repeat="foo in bar" ng-click="go_to(foo.id)" >


The go_to() function is defined in the controller scope like:

$scope.go_to = function (in_id) {
var url = "#details/" + in_id;
window.location.href = url;
};


And the #details is routed through ngRoute:

.when('/details/:id', {
templateUrl : 'foo.html',
controller : 'fooController'
})


The table-row calls the go_to function fine, but it lands the #details/x page twice in the history, where the first hit is a constant redirect to the next, so the back button is rendered useless.

IE: Say we have two pages; Main and Sub, where Main has the ng-click(go_to) functionality. Before clicking the ng-click the browser history looks like this [Main]. After clicking it, it looks like [Main, Sub, Sub]. Hitting back, no matter the amount of times, will still land you on Sub.

Is there any coherent explanation why the application behaves this way? Alternative solutions to it all are also very welcome

Answer

Since you are in an Angular application, changing pages with use of window.location.href is not the right way to do things, since it will effectively cause the whole page to reload and therefore your whole Angular application to be reloaded. What you have is a single-page application and you should treat it as such, ie. you should avoid reloading the page unless you absolutely have to.

The recommended way to do what you want is therefore to use the $location service to change the page displayed to the user. Something like

$scope.go_to = function (in_id) {
    var url = "#details/" + in_tg_id;
    $location.url(url);
 };

The $route service watches $location.url() (according to its documentation) and therefore a change in $location.url() will cause the correct route to be displayed to the user.