使用AngularJS路由保留查询字符串

时间:2013-11-13 19:46:26

标签: angularjs

我已经在一个大型Angular应用程序上工作了将近一年,而且我一直试图做我想做的事情。

以下是我使用params的两条路线(为简洁而缩短):

/a/:id
/a/:id/b

我们假设用户位于/a/1并且修改了查询字符串,例如:

/#/a/1?foo=123&bar=456

我希望在页面上有一个链接,用于在保持查询字符串的同时将用户引导到第二个路由/a/1/b,因此最终结果是重定向到:

/#/a/1/b?foo=123&bar=456

我正在使用Angular 1.2和新的ngRoute模块。

实现此行为的最佳方式是什么?


修改 我应该提一下,我现在有一个工作解决方案对我来说似乎很糟糕。该链接绑定到ng-click处理程序,该处理程序基本上如下:

$scope.navigateToBClick = function() {
  var path = $location.path() + '/b',
    search = $location.search();
  $location.url(path + '?' + $.param(search));
};

6 个答案:

答案 0 :(得分:5)

我不确定你是否会认为这是一个比你所拥有的更好的解决方案,但这是一个解决方案。

在初始化代码中,添加以下内容:

app.run(["$rootScope", function ($rootScope) {
    $rootScope.$on("$routeChangeSuccess", function (e, current) {
        $rootScope.query = $.param(current.params);
    });
}]);

然后,在您的HTML中,按如下方式创建链接:

<a ng-href="#/a/{{id}}/b?{{query}}">Navigate to B</a>

答案 1 :(得分:1)

如果我正确理解了问题,那么我们可以使用 $ locationChangeStart $ rootScope事件来解决它。这是在运行阶段完成的。 基本思路是:在每个位置更改我们将检查我们是否在url中有查询字符串(在url中搜索'?',如果有查询字符串,则我们将其添加到新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];
      }
   });

在HTML中,我们只需调用 $ location.path('a / 1 / b'),url params(查询字符串)将自动添加。

答案 2 :(得分:0)

如果路线是/#/ a / 1?foo = 123&amp; bar = 456然后重定向到/#/ a / 1 / b?foo = 123&amp; bar = 456

我曾经/#a?foo = bar到/#b?foo = bar,可以很容易地调整到/#a / b?foo = bar并使用angular-route-segment库。

http://run.plnkr.co/HvSyw4aMUiy1mwC3/#/firstRoute?foo=bar

运行plunker

并查看此处的代码

http://plnkr.co/edit/ylFM8BHRXpqpMV7QVEcJ

如果有效,请告诉我。

答案 3 :(得分:0)

到目前为止,我发现的另一个解决方案是跟踪所有$location.search()更改,并在每次搜索更改后将$window.location.search存储在范围变量中。

然后只需将此范围变量添加到模板中的所有锚点:

<a ng-href="/projects/{{ projectId }}{{ queryString }}">
    Title
</a>

在这种情况下,两个路由都从routeParams查询字符串中读取范围变量,并对这些变量使用$scope.$watch来反映$location.search中的更改,从而相应地锚定href属性。

答案 4 :(得分:0)

//控制器

$scope.menu = {path:"admin", name: "Administration"};
var queryString = $location.$$url.split("?")[1];
if (queryString) {
    $scope.queryString = "?" + queryString;
}

//视图

<a ng-href="#/{{menu.path}}{{queryString}}">{{menu.name}}</a>

答案 5 :(得分:0)

这是我使用的导致持久查询字符串传播的解决方案(我不想要)。

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);
        });
    }
});