I\'ve been working on a large Angular app for almost a year now and I\'m stuck trying to do what I expected to be trivial.
Here are two routes I have with params (sh
if route is /#/a/1?foo=123&bar=456 then redirect to /#/a/1/b?foo=123&bar=456
I have worked on /#a?foo=bar to /#b?foo=bar, it can be easily tweaked to /#a/b?foo=bar and used angular-route-segment library.
Run the plunker at http://run.plnkr.co/HvSyw4aMUiy1mwC3/#/firstRoute?foo=bar
and see the code here
http://plnkr.co/edit/ylFM8BHRXpqpMV7QVEcJ
Please let me know if it works.
Another solution I've found so far is to trace all $location.search()
changes and store $window.location.search
in a scope variable after each search change.
Then just add this scope variable to all anchors in a template:
<a ng-href="/projects/{{ projectId }}{{ queryString }}">
Title
</a>
In this case both routes reads scope variables from routeParams query string and uses $scope.$watch
on those variables to reflect changes in $location.search
and thus in anchors href
attributes accordingly.
//Controller
$scope.menu = {path:"admin", name: "Administration"};
var queryString = $location.$$url.split("?")[1];
if (queryString) {
$scope.queryString = "?" + queryString;
}
//View
<a ng-href="#/{{menu.path}}{{queryString}}">{{menu.name}}</a>
Here is the solution I used that caused persistent query string propagation (that I didn't want).
el.find('li').has('ul').on('click', 'a', function (e) {
// handle clicks manually
e.stopPropagation();
// if the anchor tag has a specific class
if (el.hasClass('link')) {
var path = el.attr('href').replace('#', '');
scope.$apply(function () {
// changing the path changes only the path
// the query string is left intact
$location.path(path);
});
}
});
If i understand correctly the question then we can solve it with $locationChangeStart $rootScope event. This is done in run phase. Basic idea is : on every location change we will check if we had query string in url (searching for '?' in the url, if there is query string , then we add it to the new url.
angular.module('your_module').run(function ($rootScope) {
$rootScope.$on('$locationChangeStart', function (event, newUrl, oldUrl) {
// If we have queryString on currentURL , then we will add it to the next url
if(oldUrl.indexOf('?') >= 0) {
// this can be optimized if we want to check first for queryString in the new url,
// then append only new params, but that's additional feature.
newUrl += '?' + oldUrl.split('?')[1];
}
});
In HTML we just call $location.path('a/1/b') , url params (query strings) will be added automatically.
I'm not sure if you would consider this a better solution than what you've got, but it is a solution.
In your initialization code, add the following:
app.run(["$rootScope", function ($rootScope) {
$rootScope.$on("$routeChangeSuccess", function (e, current) {
$rootScope.query = $.param(current.params);
});
}]);
Then, in your HTML, make your links as follows:
<a ng-href="#/a/{{id}}/b?{{query}}">Navigate to B</a>