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

Ell*_*ead 311 angularjs ngroute

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


更新:

我在下面发布了一个解决方案,但我并不完全满意.开发人员指南中的文档:Angular Services:使用$ location表示以下内容$location:

我什么时候应该使用$ location?

任何时候您的应用程序需要对当前URL中的更改做出反应,或者您想要在浏览器中更改当前URL.

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

所以:有没有$location比我在答案中更好的使用方式,或者是否有简洁的替代方案?

And*_*lin 197

您可以将$ 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'}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 雅各布是对的.他们是不同的东西.当您在angular中使用"search"时,它会将查询附加到哈希值(URL的末尾).URI的RFC规范声明查询参数应该预先添加(不附加)散列.因此,"搜索"是仅有角度将推断和解释的构造.这就是为什么只有HTML5模式才能用于上述解决方案的原因,因为无论实际的URI如何,您都将所有请求委托给一个页面(在服务器级别). (5认同)
  • 不完全..查询参数包含在带有正常路由参数的$ routeParams对象中.你可以用$ location.search()读取它们/设置它们.我会在答案中加上这个. (2认同)
  • 这只适用于你想在angularJS中使用路线的情况! (2认同)

pko*_*rce 189

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

你可以简单地使用:

$location.search().target
Run Code Online (Sandbox Code Playgroud)

访问"目标"搜索参数.

作为参考,这里是工作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);
    }
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

  • @nandin:不,你不需要***$ location.search()`周围的括号*.我不确定为什么这个答案会把它们放在那里. (21认同)
  • 我觉得@nandin误解了"你需要括号"的问题.你*需要在搜索之后需要括号,而不是整个`$ location.search()`周围的括号. (9认同)
  • 不要忘记,如果你不使用`HTML5Mode(true)`那么只有在#/可用之后才能使用params,或者在开头使用#/添加到url. (4认同)
  • 你需要围绕$ location.search()的括号吗? (2认同)
  • @Magne:是的,你需要括号,$ location.search是一个方法https://docs.angularjs.org/api/ng/service/$location (2认同)
  • @nandin,这是一个奇怪的论点 (2认同)

Ell*_*ead 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>
Run Code Online (Sandbox Code Playgroud)

关键是要$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

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

  • 看起来像从Angular 1.3开始,为了使用html5Mode,你还需要添加一个`<base href ="/"/>`标签,或者添加`requireBase:false`作为调用html5Mode的另一个参数.[详细信息](https://docs.angularjs.org/error/$location/nobase) (4认同)

Fiz*_*han 17

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

  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;
  }
Run Code Online (Sandbox Code Playgroud)
  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'
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢您的建议#/ (5认同)

Ill*_*dan 9

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

这将始终有效:

$ window.location.search


sap*_*apy 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);
 }]);
Run Code Online (Sandbox Code Playgroud)