Angular 2のURLからクエリパラメータを取得するにはどうすればよいですか?


237

私はangular2.0.0-beta.7を使用しています。コンポーネントがに/path?query=value1リダイレクトされるようなパスにロードされたとき/path。GETパラメータが削除されたのはなぜですか?パラメータを保持するにはどうすればよいですか?

ルーターにエラーがあります。のようなメインルートがある場合

@RouteConfig([
  {
      path: '/todos/...',
      name: 'TodoMain',
      component: TodoMainComponent
  }
])

と私の子供のルートのような

@RouteConfig([
  { path: '/', component: TodoListComponent, name: 'TodoList', useAsDefault:true },
  { path: '/:id', component: TodoDetailComponent, name:'TodoDetail' }
])

その後、TodoListComponentでパラメータを取得できません。私は得ることができます

params("/my/path;param1=value1;param2=value2") 

でもクラシックが欲しい

query params("/my/path?param1=value1&param2=value2")

1
これをどのように指定@RouteConfigしましたpathか?
Pankaj Parkar 2016

エラーが見つかりました。メインルートと子ルートがあり、{パス: '/ todos / ...'のようなメインルートがある場合、名前: 'TodoMain'、コンポーネント:TodoMainComponent}と子ルート{パス: '/'、コンポーネント:TodoListComponent、名前: 'TodoList'、useAsDefault:true}、それは機能せず、クエリパラメーターなしでURLにリダイレクトします。
FireGM 2016

回答:


412

のインスタンスを注入することによりActivatedRoutequeryParamsおよびオブザーバブルを含むさまざまなオブザーバブルをサブスクライブできますparams

import {Router, ActivatedRoute, Params} from '@angular/router';
import {OnInit, Component} from '@angular/core';

@Component({...})
export class MyComponent implements OnInit {

  constructor(private activatedRoute: ActivatedRoute) {}

  ngOnInit() {
    // Note: Below 'queryParams' can be replaced with 'params' depending on your requirements
    this.activatedRoute.queryParams.subscribe(params => {
        const userId = params['userId'];
        console.log(userId);
      });
  }

}

登録解除に関する注意

@Retoと@ codef0rmerは、公式のドキュメントによると、このメソッドではunsubscribe()コンポーネントonDestroy()メソッドの内部は不要であることをかなり正しく指摘していました。これは私のコードサンプルから削除されました。(このチュートリアルの青い警告ボックスを参照しください)


2
さらに、サブスクリプションをプロミスで置き換えることをお勧めします-この特別な場合。this.activatedRoute.params.toPromise().then(response => ...).catch(error => ...);
2016年

「activatedRoute」はどこに渡せますか?
michali 2016年

20
公式ドキュメントから: 退会する必要がありますか? The Router manages the observables it provides and localizes the subscriptions. The subscriptions are cleaned up when the component is destroyed, protecting against memory leaks, so we don't need to unsubscribe from the route params Observable.
2016年

サブスクリプション(またはプロミス)を起動しない角度リダイレクト。トークンで元のoAUthコールバックを確認できますが、クエリparamsなしでルートにリダイレクトされ、console.log(param)は空のオブジェクトです。
FlavorScape 2016

1
@ソブハン、はい、違いがあります。switchMapオペレーターはObservableを返しますが、subscribeオペレーターはオブザーバー(私たちのコンポーネント)がObservableによって最終的に発行されているアイテムを表示できるようにします。したがって、ドキュメントでは、switchmapの2つのインスタンスが使用されています。1)herosのリクエストを追加するために、switchMapを使用しました。SwitchMapは、サブスクライブとは異なり、ユーザーがヒーローを取得しながらルートに再度ナビゲートした場合に、リクエストがキャンセルされることを保証します。2)非同期パイプが使用されている。非同期パイプはオブザーバブルを消費するため、サブスクライブしないでください(非同期パイプがそれを行います)。
スティーブンポール

103

このようなURL http://stackoverflow.com?param1=value

次のコードでparam1を取得できます。

import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';

@Component({
    selector: '',
    templateUrl: './abc.html',
    styleUrls: ['./abc.less']
})
export class AbcComponent implements OnInit {
    constructor(private route: ActivatedRoute) { }

    ngOnInit() {
        // get param
        let param1 = this.route.snapshot.queryParams["param1"];
    }
}

2
これは、routeconfigパスに「/:id」を追加する必要がないことを意味しますか?これを使用すると「未定義」になるので、どこかにまだエラーがある
はずです

2
すごい。これは、動的サーバーのURLから直接パラメーターを読み取る必要があるため、探していました。ナビを使用できません。
The.Bear

37

この質問はバージョンベータ7を指定していますが、この質問は、angular 2クエリパラメータなどの一般的なフレーズに対するGoogleでの上位の検索結果としても表示されます。そのため、ここに最新のルーター(現時点ではalpha.7)の回答があります。

パラメータの読み取り方法が劇的に変わりました。最初に、次のRouterようなコンストラクタパラメータで呼び出される依存関係を注入する必要があります。

constructor(private router: Router) { }

その後、ngOnInitメソッドのクエリパラメータをサブスクライブできます(コンストラクタも大丈夫ですが、ngOnInitテスト容易性のために使用する必要があります)。

this.router
  .routerState
  .queryParams
  .subscribe(params => {
    this.selectedId = +params['id'];
  });

この例では、のようなURLからクエリパラメータIDを読み取りますexample.com?id=41

まだ注意すべきことがいくつかあります。

  1. paramslikeのプロパティにアクセスすると、params['id']常に文字列が返されます。これは、プレフィックスを付けることで数値に変換できます+
  2. クエリパラメータがオブザーバブルでフェッチされるのは、新しいコンポーネントをロードする代わりに同じコンポーネントインスタンスを再利用できるためです。クエリパラメータが変更されるたびに、サブスクライブした新しいイベントが発生するため、それに応じて変更に対応できます。

同じメンバーに複数のパラメーターを渡す方法はありますか?たとえば、「id」または「identification」のいずれかでthis.selectedIdに移動します。
phandinhlan

@phandinhlan:まあ、それは実際にはAngular 2に関連する問題ではありません。もちろん実装できますが、ロジックを自分で定義する必要があります。基本的にあなたがしたいことは、最初のキーが定義されているかどうかを最初にチェックし、それからのみ値を読み取ることです。定義されていない場合は、別のキーで値を読み取ります。これはのようなもので達成できますif (params.hasOwnProperty('id')) { this.selectedId = params['id'] } else { this.selectedId = params['identification']}
Roope Hakulinen 16

ええ、私はそのようなことをすることになりました。次のような「組み込み」方法があると思ったところです。this.selectedId= + params ['id']; this.selectedId = + params ['identification']; もちろん、これは意味がなく、機能しません。
phandinhlan

28

私は@StevePaulの答えが本当に好きでしたが、余分なサブスクライブ/サブスクライブ解除呼び出しなしで同じことを行うことができます。

import { ActivatedRoute } from '@angular/router';
constructor(private activatedRoute: ActivatedRoute) {
    let params: any = this.activatedRoute.snapshot.params;
    console.log(params.id);
    // or shortcut Type Casting
    // (<any> this.activatedRoute.snapshot.params).id
}

7
もちろん、これに関する警告は、それが初期値になり、その後の変更が反映されないことです。したがって、ロジックの一部としてプログラムでURLパラメータを変更する場合は、注意が必要です
両手利き

これがAngularの新しいバージョンで変更されたかどうかはわかりませんが、this.activatedRoute.snapshot.queryParamsで確認できます
Michael

21

クエリパラメータを送信するには

import { Router } from '@angular/router';
this.router.navigate([ '/your-route' ], { queryParams: { key: va1, keyN: valN } });

クエリパラメータを受信するには

import { ActivatedRoute } from '@angular/router';
this.activatedRoute.queryParams.subscribe(params => {
    let value_1 = params['key'];
    let value_N = params['keyN'];
});

公式ソース


読み取りは正常に機能しますが、大文字と小文字が区別されます。大文字と小文字を区別しないようにするにはどうすればよいですか?
姉さん

12

こんにちは、URLSearchParamsを使用できます。詳細については、こちらをご覧ください

インポート:

import {URLSearchParams} from "@angular/http";

そして機能:

getParam(){
  let params = new URLSearchParams(window.location.search);
  let someParam = params.get('someParam');
  return someParam;
}

注意:すべてのプラットフォームでサポートされているわけではなく、角度付きドキュメントでは「実験的」状態にあるようです


2
これは私にはうまくいきません。window.location.searchには、クエリ文字列パラメーターの先頭の疑問符が含まれていることがわかりました。したがって、最初のパラメータのキーには疑問符が付加されます。
AJモリス

AJモリス、あなたの問題を回避するには: if (window.location.search.indexOf('?') == 0){ normalizedQueryString = window.location.search.substring(1); } else { normalizedQueryString = window.location.search; } let params = new URLSearchParams(normalizedQueryString);
両手利きの

URLSearchParamsは非推奨です。これで、ActivatedRouteでそれを行うことができます。
Robert Blasco Villarroya

7

まず、Angular2で作業しているのは、クエリ文字列を含むURLが /path;query=value1

使用するコンポーネントでアクセスするには、次のようにしますが、コードブロックに従います。

    constructor(params: RouteParams){
    var val = params.get("query");
    }

コンポーネントをロードすると削除される理由については、これはデフォルトの動作ではありません。特にクリーンなテストプロジェクトでチェックしましたが、リダイレクトも変更もされませんでした。デフォルトのルートですか、それともルーティングについて特別なものですか?

https://angular.io/docs/ts/latest/guide/router.html#!#query-parametersの Angular2チュー​​トリアルでクエリ文字列とパラメーターを使用したルーティングについて読んでください。


「; param1 = value1; param2 = value2」のようなparamsは使用できません。このリンクは別のサイトで生成され、「example.com/auth?code_for_auth=askjfbkajdsbfksajdf」のような私のサイトにリダイレクトされます
FireGM

現時点でAngular2でルーティングを設定する方法は、実際には可能ではないと思います。子ルーティングはマトリックスURLに依存するため、何らかの回避策が必要になります。少なくとも私が知っているように。私は自分のWebサーバーでそれを傍受し、それらをハックとして変換しますが、現時点では別の方法を考えることはできません
Namirna

リンク先サイトにURLの変更を依頼する可能性はありませんか?
Namirna 2016

1
いいえ。しかし、Location.path()を手動で解析するだけで問題を解決しました
FireGM '29 / 02/29

4
このソリューションは廃止されました!

7

下記のようにActivatedRouteを使用してURLに渡されると、クエリパラメータを取得できます。

url:-http:/domain.com?test = abc

import { Component } from '@angular/core';
import { ActivatedRoute }     from '@angular/router';

@Component({
  selector: 'my-home'
})
export class HomeComponent {

  constructor(private sharedServices : SharedService,private route: ActivatedRoute) { 
    route.queryParams.subscribe(
      data => console.log('queryParams', data['test']));
  }

}

7

オブジェクトとしてURLパラメータを取得します。

import { Router } from '@angular/router';
constructor(private router: Router) {
    console.log(router.parseUrl(router.url));
}

2

クエリパラメータを1回だけ取得する場合は、takeメソッドを使用するのが最善の方法です。サブスクリプション解除について心配する必要はありません。これが簡単なスニペットです:-

constructor(private route: ActivatedRoute) {
  route.snapshot.queryParamMap.take(1).subscribe(params => {
     let category = params.get('category')
     console.log(category);
  })
}

注:今後パラメータ値を使用する場合は、take(1)を削除してください


2

今それは:

this.activatedRoute.queryParams.subscribe((params: Params) => {
  console.log(params);
});

1
このコードスニペットをありがとうございます。このコードスニペットは、短期間の限定的なヘルプを提供する場合があります。適切な説明は、なぜこれが問題の優れた解決策であるかを示すことにより、長期的な価値を大幅に改善し、他の同様の質問を持つ将来の読者にとってより有用になるでしょう。回答を編集して、説明を追加します。これには、仮定を含めます
Shawn C.

1

私はそれが他の誰かを助けることを願っています。

上記の質問では、ページがリダイレクトされた後にクエリパラメータ値が必要であり、スナップショット値(観測不可の代替)で十分であると想定できます。

公式ドキュメントの snapshot.paramMap.getについてここで言及した人はいません。

this.route.snapshot.paramMap.get('id')

送信する前に、これを送信/リダイレクトするコンポーネントに追加します。

import { Router } from '@angular/router';

次に、どちらかにリダイレクトします(ここに記載されています):

this.router.navigate(['/heroes', { id: heroId, foo: 'foo' }]);

または単に:

this.router.navigate(['/heroes', heroId ]);

ここに記載されているように、これをルーティングモジュールに追加したことを確認してください。

 { path: 'hero/:id', component: HeroDetailComponent }

そして最後に、クエリパラメータを使用する必要があるコンポーネントで

  • インポートを追加(ここに記載):

    import { Router, ActivatedRoute, ParamMap } from '@angular/router';
  • ActivatedRouteを挿入する

(ドキュメントはswitchMapもインポートし、RouterとHeroServiceも注入します。ただし、これらは監視可能な代替手段にのみ必要です-私たちの場合のようにスナップショット代替手段を使用する場合は必要ありません):

    constructor(
      private route: ActivatedRoute
    ) {}
  • そして、必要な値を取得します(ここに記載されています):

    ngOnInit() {
      const id = this.route.snapshot.paramMap.get('id');
    }

注:ROUTING-MODULEを機能モジュールに追加する場合(ドキュメントに示されているように)、APP.MODULE.tsで、インポート:[]のAppRoutingModule(またはルートレベルのアプリルートを持つ他のファイル)の前にルーティングモジュールが表示されることを確認してください。それ以外の機能ルートは見つかりません({パス: '**'、redirectTo: '/ not-found'}の後に来ると、見つからないメッセージのみが表示されるため)。


1

コンストラクターにActivatedRouteを注入し、それからparamsまたはqueryParamsにアクセスするだけです。

constructor(private route:ActivatedRoute){}
ngOnInit(){
        this.route.queryParams.subscribe(params=>{
        let username=params['username'];
      });
 }

場合によっては、NgOnInitで何も与えられない場合があります...おそらく、この場合、paramsの初期化前のinit呼び出しが原因で、関数debounceTime(1000)でオブザーバブルにしばらく待機するように依頼することでこれを実現できます。

例=>

 constructor(private route:ActivatedRoute){}
    ngOnInit(){
            this.route.queryParams.debounceTime(100).subscribe(params=>{
            let username=params['username'];
          });
     }

debounceTime()別のソースエミッションなしで特定の期間が経過した後にのみソースオブザーバブルから値を発行します


0

ルートで定義されていない場合、RouterStateからパラメーターを取得できないため、この例では、クエリ文字列を解析する必要があります...

これが私が使ったコードです:

let re = /[?&]([^=#&]+)=([^&#]*)/g;
let match;
let isMatch = true;
let matches = [];
while (isMatch) {
    match = re.exec(window.location.href);
    if (match !== null) {
        matches[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
        if (match.index === re.lastIndex) {
            re.lastIndex++;
        }
    }
    else {
        isMatch = false;
    }
}
console.log(matches);


0

クエリとパス(Angular 8)

https://myapp.com/owner/123/show?height=23のようなURLがある場合は、

combineLatest( [this.route.paramMap, this.route.queryParamMap] )
  .subscribe( ([pathParams, queryParams]) => {
    let ownerId = pathParams.get('ownerId');    // =123
    let height  = queryParams.get('height');    // =height
    // ...
  })

更新

使用this.router.navigate([yourUrl]);し、クエリパラメータがyourUrl文字列に埋め込まれている場合、URLが角度エンコードされ、次のようなものが得られますhttps://myapp.com/owner/123/show%3Fheight%323-上記のソリューションでは、間違った結果( queryParamsは空になり、クエリのパラメーターは、パスの最後にある場合、最後のパスのパラメーターに接着できます)。この場合、ナビゲーションの方法をこれに変更します

this.router.navigateByUrl(yourUrl);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.