首页 文章

在AngularJS中读取查询参数的最简洁方法是什么?

提问于
浏览
302

我想使用AngularJS读取URL查询参数的值 . 我正在使用以下URL访问HTML:

http://127.0.0.1:8080/test.html?target=bob

正如预期的那样, location.search"?target=bob" . 为了访问target的值,我发现Web上列出了各种示例,但它们都不能在AngularJS 1.0.0rc10中使用 . 特别是,以下都是 undefined

  • $location.search.target

  • $location.search['target']

  • $location.search()['target']

谁知道什么会起作用? (我使用 $location 作为我的控制器的参数)


更新:

我've posted a solution below, but I'对此并不完全满意 . Developer Guide: Angular Services: Using $location的文档说明了以下关于 $location 的内容:

我什么时候应该使用$ location?任何时候您的应用程序需要对当前URL中的更改做出反应,或者您想要在浏览器中更改当前URL .

对于我的场景,我的页面将从具有查询参数的外部网页打开,所以我本身不是"reacting to a change in the current URL" . 所以也许 $location isn 't the right tool for the job (for the ugly details, see my answer below). I' ve因此将此问题的 Headers 从"How to read query parameters in AngularJS using $location?"更改为"What's the most concise way to read query parameters in AngularJS?" . 显然我可以使用javascript和正则表达式来解析 location.search ,但是对于那些基本的东西来说,这样的低级实际上会冒犯我的程序员的敏感性 .

那么:有没有比我在答案中更好的方式使用 $location ,还是有一个简洁的备用?

11 回答

  • 55

    $ location.search()仅适用于打开HTML5模式且仅支持浏览器 .

    这将始终有效:

    $ window.location.search

  • 1

    这可能对你有所帮助

    在AngularJS中读取查询参数的最简洁方法是什么

    // Given:
    // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
    // Route: /Chapter/:chapterId/Section/:sectionId
    //
    // Then
    $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
    
    <!DOCTYPE html>
    <html ng-app="myApp">
    <head>
      <script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
      <script>
        angular.module('myApp', [], function($locationProvider) {
          $locationProvider.html5Mode(true);
        });
        function QueryCntl($scope, $location) {
          $scope.target = $location.search()['target'];
        }
      </script>
    </head>
    <body ng-controller="QueryCntl">
    
    Target: {{target}}
    </body> </html> ($location.search()).target
  • 17

    我发现对于SPA HTML5Mode会导致很多404错误问题,并且在这种情况下没有必要使$ location.search工作 . 在我的情况下,我想在用户访问我的网站时捕获URL查询字符串参数,无论他们最初链接到哪个“页面”,并且能够在他们登录后将它们发送到该页面 . 所以我只是捕获所有在app.run中的东西

    $rootScope.$on('$stateChangeStart', function (e, toState, toParams, fromState, fromParams) {
        if (fromState.name === "") {
            e.preventDefault();
            $rootScope.initialPage = toState.name;
            $rootScope.initialParams = toParams;
            return;
        }
        if ($location.search().hasOwnProperty('role')) {
            $rootScope.roleParameter = $location.search()['role'];
        }
        ...
    }
    

    然后在登录后我可以说$ state.go($ rootScope.initialPage,$ rootScope.initialParams)

  • 0

    它可以通过两种方式完成:

    • 使用 $routeParams

    最佳和推荐的解决方案是在控制器中使用 $routeParams . 它需要安装 ngRoute 模块 .

    function MyController($scope, $routeParams) {
          // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
          // Route: /Chapter/:chapterId/Section/:sectionId
          // $routeParams ==> {chapterId:'1', sectionId:'2', search:'moby'}
          var search = $routeParams.search;
      }
    
    • 使用 $location.search() .

    这里有一个警告 . 它仅适用于HTML5模式 . 默认情况下,它不适用于没有散列( # )的URL http://localhost/test?param1=abc&param2=def

    您可以通过在URL中添加 #/ 来使其工作 . http://localhost/test#/?param1=abc&param2=def

    $location.search() 返回一个对象:

    {
      param1: 'abc',
      param2: 'def'
    }
    
  • 186

    为了回答我自己的问题,这里是HTML5浏览器的工作示例:

    <!DOCTYPE html>
    <html ng-app="myApp">
    <head>
      <script src="http://code.angularjs.org/1.0.0rc10/angular-1.0.0rc10.js"></script>
      <script>
        angular.module('myApp', [], function($locationProvider) {
          $locationProvider.html5Mode(true);
        });
        function QueryCntl($scope, $location) {
          $scope.target = $location.search()['target'];
        }
      </script>
    </head>
    <body ng-controller="QueryCntl">
    
    Target: {{target}}
    </body> </html>

    关键是如上所述调用 $locationProvider.html5Mode(true); . 它现在在打开 http://127.0.0.1:8080/test.html?target=bob 时有效 . 我在旧浏览器中工作,但无论如何我可能会使用这种方法 .

    可以使用旧浏览器的替代方法是删除 html5mode(true) 调用并使用以下地址和哈希斜杠:

    http://127.0.0.1:8080/test.html#/?target=bob

    相关文档位于Developer Guide: Angular Services: Using $location(奇怪,我的谷歌搜索没有找到这个......) .

  • 2

    埃利斯怀特黑德的回答只是一个精确的问题 . 如果没有为具有 <base href=""> 标记的应用程序指定基本URL或将参数 requireBase 设置为 false$locationProvider.html5Mode(true); 将无法使用新版本的angularjs

    From the doc

    如果将$ location配置为使用html5Mode(history.pushState),则需要使用标记指定应用程序的基本URL,或者通过将带有requireBase:false的定义对象传递给$ locationProvider来将$ locationProvider配置为不需要基本标记.html5Mode():

    $locationProvider.html5Mode({
      enabled: true,
      requireBase: false
    });
    
  • 6

    只是为了总结一下 .

    如果您的应用程序是从外部链接加载的,那么angular不会将其检测为URL更改,因此$ loaction.search()将为您提供一个空对象 . 要解决此问题,您需要在应用配置(app.js)中设置以下内容

    .config(['$routeProvider', '$locationProvider', function ($routeProvider,     $locationProvider) 
    {
       $routeProvider
          .when('/', {
             templateUrl: 'views/main.html',
             controller: 'MainCtrl'
          })
          .otherwise({
             redirectTo: '/'
          });
    
          $locationProvider.html5Mode(true);
     }]);
    
  • 1

    你也可以使用$ location . $$ search.yourparameter

  • 195

    很好,你已经设法让它使用html5模式,但它也可以使其在hashbang模式下工作 .

    你可以简单地使用:

    $location.search().target
    

    访问“目标”搜索参数 .

    作为参考,这里是工作jsFiddle:http://web.archive.org/web/20130317065234/http://jsfiddle.net/PHnLb/7/

    var myApp = angular.module('myApp', []);
    
    function MyCtrl($scope, $location) {
    
        $scope.location = $location;
        $scope.$watch('location.search()', function() {
            $scope.target = ($location.search()).target;
        }, true);
    
        $scope.changeTarget = function(name) {
            $location.search('target', name);
        }
    }
    
    <div ng-controller="MyCtrl">
    
        <a href="#!/test/?target=Bob">Bob</a>
        <a href="#!/test/?target=Paul">Paul</a>
        
        <hr/>    
        URL 'target' param getter: {{target}}<br>
        Full url: {{location.absUrl()}}
        <hr/>
        
        <button ng-click="changeTarget('Pawel')">target=Pawel</button>
        
    </div>
    
  • -2

    您可以将$routeParams(需要ngRoute)注入控制器 . 以下是文档中的示例:

    // Given:
    // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
    // Route: /Chapter/:chapterId/Section/:sectionId
    //
    // Then
    $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
    

    编辑:您还可以使用$location服务(在 ng 中可用)获取和设置查询参数,尤其是 search 方法:$location.search() .

    在控制器初始加载后,$ routeParams不太有用; $location.search() 可以随时调用 .

  • 8

    这有点晚了,但我认为你的问题是你的网址 . 如果不是

    http://127.0.0.1:8080/test.html?target=bob
    

    你有过

    http://127.0.0.1:8080/test.html#/?target=bob
    

    我很确定它会起作用 . Angular非常挑剔#/

相关问题