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


312

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を変更する場合。

私のシナリオでは、私のページはクエリパラメーターを使用して外部Webページから開かれるため、それ自体は「現在のURLの変更に反応する」ことはありません。ですから、おそらく$location仕事に適したツールではありません(醜い詳細については、以下の私の答えを参照してください)。したがって、この質問のタイトルを「$ locationを使用してAngularJSでクエリパラメーターを読み取る方法」から変更しました。「AngularJSでクエリパラメータを読み取る最も簡潔な方法は何ですか?」明らかに、JavaScriptと正規表現を使用して解析することができlocation.searchますが、非常に基本的な何かのために低レベルにすると、プログラマーの感性が本当に気分を害します。

だから:$location私の答えよりも使用するより良い方法はありますか、それとも簡潔な代替手段はありますか?


1
$ location.search()['target']は機能しませんか?
rob

パスの後にハッシュがないため、これは機能しません。http://127.0.0.1:8080/test.html#?target=bob動作する、#前に注意してください?$locationサーバーに送信されない第2レベルのルーティングメソッドです。
ダニエルF

1
@DanielF @rob、あなたはどちらも正しい。最新のブラウザで呼び出された$location.search()['target']後に動作し$locationProvider.html5Mode(true)ます。
クリスピー、2016年

回答:


199

あなたは、注入することができ$ 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'}

編集:$ locationサービス(で利用可能ng)、特にそのsearchメソッドである$ location.search()を使用してクエリパラメータを取得および設定することもできます。

$ routeParamsは、コントローラーの初期ロード後はあまり役に立ちません。$location.search()いつでも呼び出すことができます。


1
提案とリンクをありがとう!私はページを読み、実際に動作するサンプルを設定しようとしました。ただし、この場合はルーティングを使用したくないので、このアプローチはうまくいきません。それでも、これは役立つ提案でした。十分なstackoverflow担当者がいれば、投票します。
エリスホワイトヘッド

1
私は言うでしょう@ pkozlowski.opensourceの答えは、このような状況では、より正確である
マルティン・コル

2
完全ではありません。クエリパラメータは、通常のルートパラメータとともに$ routeParamsオブジェクトに含まれています。そして、それらを$ location.search()で読み取り/設定できます。それを答えに追加します。
Andrew Joslin 2013

5
ヤクブは正しいです。彼らは違うものです。「検索」を角度で使用すると、クエリがハッシュ(URLの末尾)に追加されます。URIのRFC仕様では、クエリパラメータはハッシュの先頭に追加するのではなく追加する必要があると規定されています。したがって、「検索」は、角度のみが外挿して解釈する構成です。上記のソリューションでは、実際のURIに関係なくすべてのリクエストを1つのページ(サーバーレベル)に委任しているため、HTML5モードのみが機能するのはこのためです。
Steven Pena 14

2
これは、angularJSでルートを使用する場合にのみ機能します。
windmaomao

189

html5モードで正常に機能するようになりましたが、ハッシュバングモードで機能させることもできます。

あなたは単に使うことができます:

$location.search().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>


2
$ location.search()の前後に括弧が必要ですか?
Magne、2014年

2
@マグネ:はい、かっこが必要です、$ location.searchはメソッドdocs.angularjs.org/api/ng/service/$locationです
nandin

4
使用しない場合HTML5Mode(true)は、#/の後のparamsのみが使用可能であること、または先頭に#/があるURLに追加されることを忘れないでください。
セバスチャン

21
@nandin:いいえ、あなたはないではない括弧を必要とする周り $location.search()。なぜこの答えがそれらをそこに置くのか分かりません。
Dan Tao 14

9
@nandinは「括弧が必要ですか」という質問を誤解しているように感じます。検索後に括弧必要です、全体の括弧必要ありません$location.search()
K.カーペンター

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>

キーは、$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

関連ドキュメントは、開発者ガイド:Angular Services:$ locationを使用しています(私のGoogle検索でこれが見つからなかったのは奇妙です...)。


これをありがとう。クエリパラメータを読み取ろうとして、髪の毛を抜いてきました。上記のように「未定義」を取得し続けました。モードをhtml5に設定すると機能しました。
sthomps 2013年

ng-controller属性を<body>に設定する必要はありませんMyAppか?
Jago

4
Angular 1.3から始まっているように見えますが、html5Modeを使用するには、<base href="https://stackoverflow.com/" />タグを追加するかrequireBase: false、html5Modeの呼び出しに別のパラメーターとして追加する必要があります。詳細はこちら
dae721

17

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

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

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

{
  param1: 'abc',
  param2: 'def'
}

5
#/
yonexbat

9

$ location.search()は、HTML5モードがオンで、サポートされているブラウザーでのみ機能します。

これは常に機能します:

$ window.location.search


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);
 }]);

1
うん。これは見つけるのが大変でした。コメントをありがとう。
mikeborgh

2

エリスホワイトヘッドの答えの正確さ。タグで$locationProvider.html5Mode(true);アプリケーションのベースURLを指定する<base href="">か、パラメータrequireBaseをに設定しないと、angularjsの新しいバージョンでは動作しませんfalse

ドキュメントから

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

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

1

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


18
$$search内部変数、このような良いアイデアではありませんこれを使用することです。
kumarharsh 2013

1

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

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

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

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


-3

少し遅いですが、問題はURLにあったと思います。代わりに

http://127.0.0.1:8080/test.html?target=bob

持っていた

http://127.0.0.1:8080/test.html#/?target=bob

私はそれがうまくいったと確信しています。Angularはその#/について本当にうるさいです


HTML5モードを有効にしていない場合のみです。#/は常にAngular URLにあるわけではありません。
LocalPCGuy 2016年

SPAを構築している場合です。すべてのURLに#があります。また、HTML5Modeは、1)ページの更新時に404、2)ダイレクトURLが機能しないことを意味します。支払うのに高額のようです。
nuander 2018年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.