318

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

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

正如所料,location.search"?target=bob"。为了访问target的值,我在网上找到了各种示例,但它们都不适用于 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 和正则表达式来 parse location.search,但是为了一些如此基本的东西而去低级真的冒犯了我的程序员的敏感性。

$location那么:有没有比我的答案更好的使用方法,还是有简洁的替代方法?

4

10 回答 10

200

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

于 2012-06-16T14:57:17.570 回答
191

很好,您已经设法让它在 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>

于 2012-07-16T17:56:48.600 回答
57

为了部分回答我自己的问题,这里是 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)调用并使用带有哈希+斜线的以下地址:

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

相关文档位于开发人员指南:Angular Services: Using $location(奇怪的是我的谷歌搜索没有找到这个......)。

于 2012-06-17T06:37:15.403 回答
19

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

  1. 使用$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;
  }
  1. 使用$location.search().

这里有一个警告。它仅适用于 HTML5 模式。默认情况下,它不适用于其中没有 hash( #)的 URLhttp://localhost/test?param1=abc&param2=def

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

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

{
  param1: 'abc',
  param2: 'def'
}
于 2015-07-21T18:40:49.433 回答
10

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

这将始终有效:

$window.location.search

于 2015-07-11T13:08:57.537 回答
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);
 }]);
于 2014-04-19T18:45:26.570 回答
2

只是对埃利斯怀特黑德的回答的精确。$locationProvider.html5Mode(true);如果不使用<base href="">标签指定应用程序的基本 URL 或将参数设置requireBasefalse

从文档

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

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});
于 2016-02-11T12:44:37.663 回答
1

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

于 2013-08-05T11:17:00.423 回答
1

我发现对于 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)

于 2018-01-11T00:51:35.100 回答
-3

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

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

你有过

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

我很确定它会奏效的。Angular 对它的 #/ 真的很挑剔

于 2016-03-10T16:49:00.797 回答