Angular:ルートを変更せずにqueryParamsを更新する方法


125

コンポーネントからqueryParamsを更新(追加、削除)しようとしています。angularJSでは、これは以前は次のおかげで可能でした:

$location.search('f', 'filters[]'); // setter
$location.search()['filters[]'];    // getter

ユーザーがフィルタリング、並べ替えなどができるリストを備えたアプリがあり、URLのqueryParamsですべてのフィルターをアクティブに設定して、ユーザーがURLをコピー/貼り付けしたり、他のユーザーと共有したりできるようにしたいと考えています。

しかし、フィルターが選択されるたびにページがリロードされることを望みません

これは新しいルーターで可能ですか?

回答:


270

新しいクエリパラメータを使用して現在のルートに移動できます。これにより、ページは再読み込みされませんが、クエリパラメータが更新されます。

(コンポーネント内)のようなもの:

constructor(private router: Router) { }

public myMethodChangingQueryParams() {
  const queryParams: Params = { myParam: 'myNewValue' };

  this.router.navigate(
    [], 
    {
      relativeTo: activatedRoute,
      queryParams: queryParams, 
      queryParamsHandling: 'merge', // remove to replace all query params by provided
    });
}

ページをリロードしない一方で、ブラウザの履歴に新しいエントリをプッシュすることに注意してください。そこに新しい値を追加するのではなく、履歴でそれを置き換えたい場合は、を使用できます{ queryParams: queryParams, replaceUrl: true }

編集:コメントですでに指摘したように、私の元の例で[]relativeToプロパティが欠落していたため、クエリパラメータだけでなく、ルートも変更された可能性があります。this.router.navigateこの場合の適切な使用法は次のとおりです。

this.router.navigate(
  [], 
  {
    relativeTo: this.activatedRoute,
    queryParams: { myParam: 'myNewValue' },
    queryParamsHandling: 'merge'
  });

新しいパラメータ値をに設定するnullと、URLからパラメータが削除されます。


30
私が使用していた[]の代わりに、['.']それを動作させるために
ハイメ・ゴメスを

5
queryParams ['relativeTo'] = this.activatedRoute;を使用する必要があります。現在のページを基準にしてナビゲーションを作成するには
klonq

3
OPの問題を解決するための素晴らしい解決策。私が何かを見落とさない限り、それがあなたを手に入れられないのは、現在のページの履歴を前後に移動し(たとえば、フィルターを変更したり、5回注文したり、それぞれ独自のURLを持つが同じコンポーネントを持っている)、ページのコンテンツは、これらの5つのURLに直接アクセスした場合と同じように表示されます。私はこれを介して手動でこれを達成this.activatedRoute.queryParams.subscribeし、コンポーネントでさまざまな更新を行うことができると思いますが、バックとフォワードが自動的に機能するようにルートをロードする単純なAngularの方法はありますか?
jmq 2018年

1
router.navigateを使用すると、ウィンドウの上部がスクロールされます。これを無効にする方法はありますか?
Hese

1
@ヘーズ、よろしいですか?一番上までスクロールするとは思いません。この例を見てください:stackblitz.com/edit/angular-sdtsew?file
src/app/…–RadosławRoszkowiak

23

@RadosławRoszkowiakの答えはrelativeTo: this.route、以下のように要求されることを除いて、ほぼ正しいです。

constructor(
  private router: Router,
  private route: ActivatedRoute,
) {}

changeQuery() {
  this.router.navigate(['.'], { relativeTo: this.route, queryParams: { ... }});
}

14

Angular 5では、現在のURLを解析することにより、urlTreeのコピーを簡単に取得および変更できます。これには、クエリパラメータとフラグメントが含まれます。

  let urlTree = this.router.parseUrl(this.router.url);
  urlTree.queryParams['newParamKey'] = 'newValue';

  this.router.navigateByUrl(urlTree); 

クエリパラメータを変更するための「正しい方法は」とおそらく createUrlTree私たちが使用して、それを修正させながら電流から新しいUrlTreeを作成し、それ以下のようなNavigationExtrasを

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

constructor(private router: Router) { }

appendAQueryParam() {

  const urlTree = this.router.createUrlTree([], {
    queryParams: { newParamKey: 'newValue' },
    queryParamsHandling: "merge",
    preserveFragment: true });

  this.router.navigateByUrl(urlTree); 
}

この方法でクエリパラメータを削除するには、undefinedまたはに設定しますnull


2
navigateByUrldiffreentであるnavigateだけでなくUrlTreeのPARAMとは- 。stackoverflow.com/a/45025432/271012を
ドレナイ

9

試す

this.router.navigate([], { 
  queryParams: {
    query: value
  }
});

単一引用符以外の同じルートナビゲーションで機能します。


私はこの正確なものを探していました。ありがとうございました!!!
cevaris

7

ほとんどの投票の答えは部分的に私のために働いた。ブラウザーのURLは同じままでしたが、routerLinkActiveナビゲーション後は動作しなくなりました。

私の解決策は、lotation.goを使用することでした:

import { Component } from "@angular/core";
import { Location } from "@angular/common";
import { HttpParams } from "@angular/common/http";

export class whateverComponent {
  constructor(private readonly location: Location, private readonly router: Router) {}

  addQueryString() {
    const params = new HttpParams();
    params.append("param1", "value1");
    params.append("param2", "value2");
    this.location.go(this.router.url.split("?")[0], params.toString());
  }
}

HttpParamsを使用してクエリ文字列を作成したのは、それを使用してhttpClientで情報を送信していたためです。しかし、あなた自身でそれを構築することができます。

とはthis._router.url.split("?")[0]、現在のURLから以前のクエリ文字列をすべて削除することです。


4
これは受け入れられる答えである必要があります。router.navigatesはngOnitも更新します。location.goはこれを行いません!コンポーネントがngOnitロジック(HTTP呼び出しなど)を実行する場合、router.navigateを使用するとそれらが再度呼び出されるため、これは非常に重要です。あなたはこれを望まない。
Danny Hoeve

なぜあなたはルーターが必要なのですか?this.location.path().split...良くないですか?
ウラジミール

@ウラジミールあなたは正しいかもしれません、私は私のコンポーネントで他の目的のためにそれを使用していたので、それだけではありませんでした。検証する時間がありません。
moi_meme

これは、プロモーションやGoogleトラッキングパラメータなどのクエリパラメータを保持する場合には機能しません
Jon Tinsman

5

と組み合わせることになりurlTreeましたlocation.go

const urlTree = this.router.createUrlTree([], {
       relativeTo: this.route,
       queryParams: {
           newParam: myNewParam,
       },
       queryParamsHandling: 'merge',
    });

    this.location.go(urlTree.toString());

toString問題を引き起こす可能性があるかどうかはわかりませんが、残念ながらlocation.go、文字列ベースのようです。


4

ルートを変更せずにクエリパラメータを変更する場合。以下の例を参考にしてください:現在のルートは/ searchであり、 ターゲットルートは(リロードページなし):/ search?query = love

submit(value: string) {
{ this.router.navigate( ['.'],  { queryParams: { query: value } })
    .then(_ => this.search(q));
}
search(keyword:any) { 
//do some activity using }

注意:this.router.navigate(['。']の代わりにthis.router.navigate([' search']を使用できます


[。]の方が。よりも良い方法であるかどうかはわかりませんrelativeTo:が、.then()役に立ちました。navigate()がpromiseを返したことを認識していなかったため、投稿してよかったです!
ドレナイ2018

0

最初に、角度ルーターからルーターモジュールをインポートし、そのエイリアス名を宣言する必要があります

import { Router } from '@angular/router'; ---> import
class AbcComponent implements OnInit(){
constructor(
    private router: Router ---> decalre alias name
  ) { }
}

1. "router.navigate"関数を使用してクエリパラメータを変更し、クエリパラメータを渡すことができます

this.router.navigate([], { queryParams: {_id: "abc", day: "1", name: "dfd"} 
});

現在のアクティブ化されたルートのクエリパラメータを更新します

  1. 以下は、_id、日、名前をクエリパラメータとして持つabcページにリダイレクトします。

    this.router.navigate(['/ abc']、{queryParams:{_id: "abc"、day: "1"、name: "dfd"}});

    3つのクエリパラメータとともに「abc」ルートのクエリパラメータを更新します

クエリパラメータを取得する場合:-

    import { ActivatedRoute } from '@angular/router'; //import activated routed

    export class ABC implements OnInit {

    constructor(
        private route: ActivatedRoute //declare its alias name
      ) {}

    ngOnInit(){
       console.log(this.route.snapshot.queryParamMap.get('_id')); //this will fetch the query params
    }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.