在angular`redirectTo`中保留`$ location.search()`?

时间:2015-06-09 13:26:28

标签: javascript angularjs routes

如何使用

保留char tempBuf[12]; ofstream myfile; myfile.open("C:\\CRC.txt"); for (i = 0; i < 200; i++, id++) { sprintf(tempBuf, "%011d", id); myfile << tempBuf << ' '; sprintf(tempBuf, "%03d", computeCrc(tempBuf)); myFile << tempBuf << '\n'; } myfile.close();
$location.search()

我知道,我可以在那里使用一个函数,它将旧对象$routeProvider.otherwise({redirectTo: xxx}) 作为第三个参数。我主要关心一把钥匙,让我们称之为$location.search(),我试过

a

但它始终以function(a, b, search) { return "/mainpage?a=" + search[a]; } 结尾。更糟糕的是,它崩溃了我的调试器,这让我感到沮丧。此外,这对所有密钥都不起作用(我稍后可能需要)。

3 个答案:

答案 0 :(得分:2)

我制作了一种新方法,您可以在其中监听$routeChangeStart并修改search(),如果之前(不存在的)页面包含重要的 GET参数。完整的来源和演示可以在this Plunker找到。

这个概念类似于@Mikko的解决方案,但实现有点不同(没有自定义提供程序),它按照作者的指示工作。

精华

angular.module('myApp').run(['$rootScope', '$location', 'URL', function($rootScope, $location, URL) {

    // Previous search() value
    var prevSearch = {};

    // Listen to event
    $rootScope.$on('$routeChangeStart', function(evt, next, current) {

        // Have search() parameters and are going to default route
        if(prevSearch !== undefined && $location.path().endsWith(URL.defaultRoute)) {

            // Extract only important params
            var important = {};
            var importantCount = 0;

            for(var param in prevSearch) {

                if(URL.importantParams.indexOf(param) > -1) {

                    important[param] = prevSearch[param];
                    importantCount++;

                }

            }

            // Unset prevSearch
            prevSearch = {};

            // Apply important params, if any
            if(importantCount > 0) {

                $location.search(important);

            }


        } else {

            // Remember current search()
            prevSearch = $location.search();

        }

    });

}]);

run函数为$routeChangeStart设置一个监听器,并且还记住search()值的先前值(GET参数)。

当应用程序重定向到默认路由时,它会检查search()参数的先前值,并仅提取重要值。如果有,它会覆盖search()值,因此将重要的GET参数设置为默认路由。

我创建了一个URL常量,可以设置默认路由并指定重要参数。代码如下:

angular.module('myApp').constant('URL', {
    defaultRoute: '/mainpage',
    importantParams: ['a', 'b'],
});

演示

first 链接在不存在的URL上包含3个参数。页面被正确地重定向到默认路由,只保留了2个重要路由。

第二个第四个链接不包含任何参数,并且两个链接都不会应用任何其他参数(无论您在单击它们时在哪个页面上)

第三个​​链接在默认路由上还包含3个参数,并且所有这些参数都被保留(不会发生重定向)。

答案 1 :(得分:1)

主要问题是,在配置阶段(.config()功能),您只能注入提供者。由于$location不是提供者,因此您无法注入它。因此$location.search()无效。

但是,您可以使用纯JavaScript window.location.hash来获取网址参数。但是,这不是 Angular方式,并且它不能按照您的意愿工作。

例如,如果您使用以下配置代码:

angular.module('myApp').config(['$routeProvider', function($routeProvider) {

    // Return $location.search() equivalent object
    function locationSearch() {

        var search = {};
        var hash = window.location.hash;
        var index = hash.indexOf('?');

        // Has parameters
        if(index > -1) {

            // Extract only the params
            var params = hash.substring(index + 1);

            // Split parameters
            params = params.split('&');

            var tmp;
            for(var i = 0, len = params.length; i < len; i++) {

                tmp = params[i].split('=');
                search[tmp[0]] = tmp[1];

            }

        }

        return search;

    }

    // Generate default URL
    function defaultURL(search) {

        if(search.a === undefined) {

            return '/mainpage';

        } else {

            return '/mainpage?a=' + search.a;

        }

    }

    // Equivalent of $location.search()
    var search = locationSearch();

    // Set up routing
    $routeProvider

        // Events
        .when('/test', {
            templateUrl: 'test.html',
            controller: 'TestCtrl'
        })

        // Default page
        .otherwise({
            redirectTo: defaultURL(search)
        });

}]);

使用上面的代码,您可以访问等效的$location.search(),并将动态URL编译为默认路由 - ngRoute 将其转义

例如,defaultURL()函数产生如下内容:/mainpage?a=123。但是,ngRoute会转义特殊字符(例如?&),并且您会被重定向到/mainpage%3Fa=123,而.config()并没有按预期工作。

此外,这仅适用于新近打开包含该网址的网页时。如果您已经在页面上并更改为无效的URL,则上述代码不起作用,因为配置阶段已经完成 - $routeProvider.otherwise()每次加载时仅触发一次。

<强> TL; DR

据我所知,在配置阶段使用<section id="justified"> <a href="project-page1.html"> <img src="img/justified1.jpg"/> </a> <a href="project-page2.html"> <img src="img/justified2.jpg"/> </a> </section> 方法无法做到这一点。

答案 2 :(得分:1)

您可以在providerconfig阶段创建自己的run,以保留搜索参数。

假设您有以下内容:

angular.module('app', ['ngRoute'])
  .provider('myRoute', function myRouteProvider() {
    var defaultUrl;
    var search;

    // get default url with params (config phase)
    this.default = function() {
      var params = '';
      angular.forEach(search, function(value, key) {
        params = params + key + '=' + value + '&';
      });

      if (params.length > 0) {
        params = params.substring(0, params.length - 1);
      }

      var redirectUrl = defaultUrl + (params ? '?' + params : '');
      console.log(redirectUrl);
      return redirectUrl;
    };

    this.$get = function($rootScope) {
      var myRoute = {};

      // set default url (run phase)
      myRoute.setDefault = function(url) {
        if (defaultUrl) {
          throw 'Provider already initialized';
        }

        defaultUrl = url;

        // update params on route change
        $rootScope.$on('$routeChangeStart', function(event, next, current) {
          search = current.params;
        });
      };

      return myRoute;      
    };
  }) 

  .config(function($routeProvider, myRouteProvider) {
    $routeProvider
      .when('/main', {
        templateUrl: 'template.html',
        controller: 'Ctrl'
      })
      .when('/route1', {
        templateUrl: 'template.html',
        controller: 'Ctrl'
      })
      .when('/route2', {
        templateUrl: 'template.html',
        controller: 'Ctrl'
      })
      .otherwise({
        // redirect to default url with latest params
        redirectTo: myRouteProvider.default
      });
  })

  .run(function(myRoute) {
    // set default url (404)
    myRoute.setDefault('/main');
  })

  .controller('Ctrl', function($scope, $location) {
    $scope.$location = $location;
  });

index.html只包含

<div>
  <a href="#/main">main</a><br>
  <a href="#/route1">route1</a><br>
  <a href="#/route2?param=abc">route2?param=abc</a><br>
  <a href="#/404">otherwise</a><br>
</div>
<hr>
<div ng-view></div> 

和路线'template.html只是

<div>
  path: {{ $location.path() }}
  <br>
  params: {{ $location.search() }}
</div>

现在,如果您在链接之间导航并点击othwerwise,您将被重定向到/main,其中包含之前路线中的任何params

imgur

此处相关的plunker http://plnkr.co/edit/cqR2Nh