web-dev-qa-db-ja.com

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

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を使うより良い方法があるのでしょうか、それとも簡潔な代替策があるのでしょうか。

306
Ellis Whitehead

あなたは $ routeParamsngRoute が必要)をあなたのコントローラーに注入することができます。これは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()はいつでも呼び出すことができます。

195
Andrew Joslin

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

私自身の質問に部分的な答えをするために、これは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検索でこれが見つからなかったのは不思議です...)。

56
Ellis Whitehead

それには2つの方法があります。

  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モードでのみ動作します。デフォルトでは、ハッシュ(#)が含まれていないURLでは機能しませんhttp://localhost/test?param1=abc&param2=def

URLに#/を追加することで機能させることができます。 http://localhost/test#/?param1=abc&param2=def

次のようなオブジェクトを返す$location.search()

{
  param1: 'abc',
  param2: 'def'
}
17
Fizer Khan

$ location.search()はHTML 5モードがオンになっていて、サポートしているブラウザでのみ動作します。

これは常に機能します。

$ window.location.search

9
Illidan

要約するだけです。

あなたのアプリが外部リンクからロードされているのであれば、$ 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);
 }]);
6
sapy

Ellis Whiteheadの答えに対する正確さです。アプリケーションのベースURLを<base href="">タグで指定したり、パラメータrequireBasefalseに設定したりしないと、$locationProvider.html5Mode(true);は新しいバージョンのangularjsでは機能しません。

ドキュメントから

Html5Mode(history.pushState)を使用するように$ locationを設定する場合は、タグを使用してアプリケーションのベースURLを指定するか、requireBase:falseを持つ定義オブジェクトを$ locationProviderに渡してベースタグを要求しないように$ locationProviderを設定する必要があります。 html5Mode():

$locationProvider.html5Mode({
  enabled: true,
  requireBase: false
});
2
S.Thiongane

$ locationを使用することもできます。

1
thewindev

これはあなたを助けるかもしれません

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

私は、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)を言うことができます

0
nuander