AngularJSでクエリパラメータを読み取る最も簡潔な方法は何ですか?

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]1のドキュメントでは、$locationについて以下のように書かれています。

どのような場合に$locationを使用するのですか? となっています。 アプリケーションが現在のURLの変更に反応する必要がある場合や アプリケーションが現在のURLの変更に対応する必要がある場合や、ブラウザで現在のURLを変更したい場合などです。

私のシナリオでは、私のページはクエリパラメータを持つ外部のウェブページから開かれますので、それ自体は現在のURLの変更に反応しているわけではありません。 つまり、$locationはこの仕事に適したツールではないのかもしれません(醜い詳細については、以下の私の回答を参照してください)。そこで私は、この質問のタイトルを「"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を使うのに、私の回答よりも良い方法があるのか、あるいは簡潔な代替案があるのかを教えてください。

コントローラに$routeParams (requirengRoute)を注入することができます。ここではその例を紹介します。

// 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'}

EDIT: $locationサービス(ngで利用可能)、特にそのsearchメソッドでも、クエリパラメータを取得・設定することができます。$location.search()です。

$routeParamsは、コントローラが最初にロードされた後はあまり意味がありません。

解説 (6)

html5モードで動作させることができて良かったですが、hashbangモードでも動作させることができます。

単純に使用することができます。

$location.search().target

とすれば、 '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/>

    target=Pawel

</div>
解説 (12)

自分の質問に対する答えの一部として、HTML5ブラウザ用の動作サンプルを紹介します。




  <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>



Target: {{target}}<br/>


キーとなるのは、上記のように $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にあります(グーグルで検索しても出てこないのが不思議ですが...)。

解説 (3)