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は、コントローラが最初にロードされた後はあまり意味がありません。
html5モードで動作させることができて良かったですが、hashbangモードでも動作させることができます。
単純に使用することができます。
$location.search().target
とすれば、 'target'の検索パラメータにアクセスできます。
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>
自分の質問に対する答えの一部として、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
関連するドキュメントは、Developer Guide: Angular Services: Using $locationにあります(グーグルで検索しても出てこないのが不思議ですが...)。