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

时间:2012-06-16 13:03:52

标签: angularjs ngroute

我想使用AngularJS读取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作为我的控制器的参数)


更新

我在下面发布了一个解决方案,但我并不完全满意。 Developer Guide: Angular Services: Using $location上的文档说明了以下关于$location

的内容
  

我应该何时使用$ location?

     

您的应用程序需要对当前的更改做出反应   URL或者您想要在浏览器中更改当前URL。

对于我的场景,我的页面将从具有查询参数的外部网页打开,因此我本身并不“对当前URL的更改作出反应”。所以也许$location不适合工作(对于丑陋的细节,请参阅下面的答案)。因此,我更改了“如何使用$ location在AngularJS中读取查询参数?”这个问题的标题。 “在AngularJS中读取查询参数的最简洁方法是什么?”显然,我可以使用javascript和正则表达式来解析location.search,但是对于那些基本的东西来说,这样的低级实际上会冒犯我的程序员的敏感性。

那么:使用$location的方式比我的回答更好吗,还是有简洁的备用方式?

11 个答案:

答案 0 :(得分:195)

您可以将$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()可以随时调用。

答案 1 :(得分:188)

很好,你已经设法让它使用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 :(得分:56)

为了回答我自己的问题,这里有一个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}}<br/>

</body>
</html>

关键是如上所述致电$locationProvider.html5Mode(true);。它现在在打开http://127.0.0.1:8080/test.html?target=bob时有效。我不满意它在旧浏览器中不起作用的事实,但无论如何我都可以使用这种方法。

可以与旧浏览器一起使用的替代方法是删除html5mode(true)调用并使用以下地址替换为hash +斜杠:

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

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

答案 3 :(得分:17)

可以通过两种方式完成:

  1. 使用$routeParams
  2. 最佳和推荐的解决方案是在控制器中使用$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;
      }
    
    1. 使用$location.search()
    2. 这里有一个警告。它仅适用于HTML5模式。默认情况下,它不适用于其中没有哈希(#)的网址http://localhost/test?param1=abc&param2=def

      您可以通过在网址中添加#/来使其发挥作用。 http://localhost/test#/?param1=abc&param2=def

      $location.search()返回如下对象:

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

答案 4 :(得分:9)

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

这将始终有效:

$ window.location.search

答案 5 :(得分:6)

只是为了总结一下。

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

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

      $locationProvider.html5Mode(true);
 }]);

答案 6 :(得分:2)

对埃利斯怀特黑德的回答只是一个精确的答案。如果未指定具有$locationProvider.html5Mode(true);代码的应用的基本网址或将参数<base href="">设置为requireBase

false将无法使用新版本的angularjs

From the doc

  

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

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

答案 7 :(得分:1)

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

答案 8 :(得分: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}}<br/>

</body>
</html>

($location.search()).target

答案 9 :(得分:0)

我发现对于SPA HTML5Mode会导致很多404错误问题,并且在这种情况下没有必要使$ location.search工作。在我的情况下,我想在用户访问我的网站时捕获URL查询字符串参数,无论哪个&#34; page&#34;他们最初链接到,并且能够在他们登录后将它们发送到该页面。所以我只是在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)

答案 10 :(得分:-3)

有点晚了,但我认为您的问题是您的网址。如果不是

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

你有

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

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

相关问题