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サービス:$ locationの使用 のドキュメントには、$location
について次のように記載されています。
いつ$ locationを使うべきですか?
アプリケーションが現在のURLの変更に対応する必要があるとき、またはブラウザで現在のURLを変更したいときはいつでも。
私のシナリオでは、私のページはクエリパラメータで外部のWebページから開かれるので、私はそれ自体「現在のURLの変更に反応する」というわけではありません。そのため、$location
がその仕事に適したツールではないかもしれません(醜い詳細については、以下の私の答えを参照してください)。そのため、この質問のタイトルを「AngularJSで$ locationを使用してクエリパラメータを読み取る方法」から変更しました。 "AngularJSでクエリパラメータを読み取る最も簡潔な方法は何ですか?" location.search
を解析するのにjavascriptと正規表現を使うことができるのは明らかですが、そのような低レベルなものを基本的なものにすることは私のプログラマーの感覚を害します。
それで、私の答えよりも$location
を使うより良い方法があるのでしょうか、それとも簡潔な代替策があるのでしょうか。
あなたは $ routeParams ( ngRoute が必要)をあなたのコントローラーに注入することができます。これはdocsからの例です:
// 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 service(ng
で利用可能)でクエリパラメータを取得して設定することもできます。特にsearch
メソッド: $ location.search() 。
$ routeParamsはコントローラの初期ロード後はあまり役に立ちません。 $location.search()
はいつでも呼び出すことができます。
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/>
<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)
呼び出しをやめて、代わりに次のアドレスをhash + slashで使うことです:
http://127.0.0.1:8080/test.html#/?target=bob
関連ドキュメントは 開発者ガイド:Angularサービス:$ locationの使用 (私のGoogle検索でこれが見つからなかったのは不思議です...)。
それには2つの方法があります。
$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;
}
$location.search()
を使う.ここに警告があります。 HTML5モードでのみ動作します。デフォルトでは、ハッシュ(#
)が含まれていないURLでは機能しませんhttp://localhost/test?param1=abc¶m2=def
URLに#/
を追加することで機能させることができます。 http://localhost/test#/?param1=abc¶m2=def
次のようなオブジェクトを返す$location.search()
:
{
param1: 'abc',
param2: 'def'
}
$ location.search()はHTML 5モードがオンになっていて、サポートしているブラウザでのみ動作します。
これは常に機能します。
$ window.location.search
要約するだけです。
あなたのアプリが外部リンクからロードされているのであれば、$ loaction.search()があなたに空のオブジェクトを与えるので、AngularはURLの変更としてこれを検出しません。これを解決するには、アプリの設定(app.js)で以下を設定する必要があります。
.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider)
{
$routeProvider
.when('/', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
}]);
Ellis Whiteheadの答えに対する正確さです。アプリケーションのベースURLを<base href="">
タグで指定したり、パラメータrequireBase
をfalse
に設定したりしないと、$locationProvider.html5Mode(true);
は新しいバージョンのangularjsでは機能しません。
ドキュメントから :
Html5Mode(history.pushState)を使用するように$ locationを設定する場合は、タグを使用してアプリケーションのベースURLを指定するか、requireBase:falseを持つ定義オブジェクトを$ locationProviderに渡してベースタグを要求しないように$ locationProviderを設定する必要があります。 html5Mode():
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$ locationを使用することもできます。
これはあなたを助けるかもしれません
Angular JSでクエリパラメータを読み取るための最も簡潔な方法は何ですか?
// 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
私は、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)を言うことができます