Angular 2でリロードせずにルートパラメーターを変更する


112

Angular 2、Google Mapsなどを使用して不動産Webサイトを作成しています。ユーザーがマップの中心を変更すると、APIに対して検索を実行して、マップの現在の位置と半径を示します。重要なのは、ページ全体を再読み込みせずに、これらの値をURLに反映したいということです。それは可能ですか?AngularJS 1.xを使用していくつかのソリューションを見つけましたが、Angular 2については何も見つかりませんでした。


[routerLink] = "['/ route'、{param1:value1}]を使用すると、ページがリロードされないと思います
Toolkit

しかし、別のクエリパラメータを追加するにはどうすればよいですか?
ツールキット

2
☝️ページの再読み込みが発生します
LifterCoder

SSRを使用してサイトをSEO互換にする場合、これは重要な問題です。
ジョナサン

@ジョナサン、そうですか?Angularは静的ページがレンダリングされるとルーティングを引き継ぐため、SSRを使用する場合でも、それは依然として有効な質問だと思います。
adam0101

回答:


90

location.go(url)アプリケーションのルートを変更せずに、基本的にURLを変更する方法を使用できます。

これは、現在のルートから子ルートへのリダイレクトのような他の影響を引き起こす可能性があることに注意してください。

説明location.goする関連する質問は、Router変化を起こすのに親密ではありません。


2
私のルートには 'search'という名前のパラメーターがあり、検索フィールドのシリアル化されたバージョンを受け取ります。リストの状態が初めて読み込まれるとき、this._routeParams.get( 'search')を使用してこれらのパラメーターのみを読み取り、フィルターをデシリアライズします検索を実行します。ユーザーがマップまたは検索ファセットのいずれかを使用して検索フィールドを変更した場合は、router var method = this._router.generate(['Listing'、{search:serializedFields}]のメソッドgenerateを使用して正しいURLを作成します)次にthis._location.go(instruction.urlPath)を使用して、状態をリロードせずにURLを変更します。
Marcos Basualdo、2016

20
他の誰かが疑問に思っている場合: 'angular2 / platform / common'から{Location}をインポートします。
ケサリオン2016年

18
import { Location } from '@angular/common';Angular 4で
tehCivilian 2017

2
あなたは次のようにconstructr decaredましたconstructor(private location: Location){ }
パンカジパーカー

2
@AdrianE問題はおそらくあなたがタイプlocation.go()すべきだったのにあなたがタイプしたことですthis.location.go()。を発行するときはthis.、Typescriptのロケーションインターフェイスを呼び出します。
georg-un

94

RC6以降、次のようにして状態を変更せずにURLを変更し、それによりルート履歴を保持できます

import {OnInit} from '@angular/core';

import {Location} from '@angular/common'; 
// If you dont import this angular will import the wrong "Location"

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.replaceState("/some/newstate/");
  }
}

これは私にはうまくいきません。それはルートをロードしようとします。コンソールエラー:Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'some/newstate'
Inigo

2
これを@golfadasによって提案されたURL作成と組み合わせると、勝者がいます!
crowmagnumb 2017年

63

使用location.go(url)する方法ですが、URLをハードコーディングする代わりに、を使用して生成することを検討してくださいrouter.createUrlTree()

次のルーター呼び出しを実行したい場合:this.router.navigate([{param: 1}], {relativeTo: this.activatedRoute})コンポーネントをリロードせずに、次のように書き換えることができます。

const url = this.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()

 this.location.go(url);

9
この答えは私の問題を解決しました。質問の1つは、上記で生成されたURLのパラメーターが ";"(セミコロン)で区切られていることです。クエリの各パラメータを「&」で区切るにはどうすればよいですか?
Amarnath

2
これはcreateUrlTree(commands:any []、navigationExtras ?: NavigationExtras)の宣言です。カンマではなく、navigationExtrasにあるqueryParamsを使用する必要があります。createUrlTree([]、{relativeTo:this.activatedRoute、queryParams:{param:1}})
キット

:ちょうど@kitが言った上で明確にするために、これを行うthis.router.createUrlTree([], {relativeTo: this.activatedRoute, queryParams: {param: 1}}).toString()
bluegrounds

12

私のような人がこの質問を見つけた場合、次の情報が役に立ちます。

私は同様の問題があり、ここの他の回答で提案されているように、最初にlocation.goとlocation.replaceStateを使用してみました。しかし、ナビゲーションが現在のルートに関連しており、現在のルートがlocation.goまたはlocation.replaceStateによって更新されていなかったため、アプリの別のページに移動しなければならないときに問題が発生しました(ルーターは何も認識していません)これらがURLに何をするかについて)

本質的には、ルートパラメータが変更されてもDIDが内部的にルート状態を更新するときに、ページ/コンポーネントを再読み込みしないソリューションが必要でした。

クエリパラメータを使用してしまいました。詳しくは、https//angular-2-training-book.rangle.io/handout/routing/query_params.htmlをご覧ください。

したがって、注文を保存して注文IDを取得する必要がある場合は、以下のようにページのURLを更新できます。地図上の中心位置と関連データの更新も同様です

// let's say we're saving an order. Initally the URL is just blah/orders
save(orderId) {
    // [Here we would call back-end to save the order in the database]

    this.router.navigate(['orders'], { queryParams: { id: orderId } });
    // now the URL is blah/orders?id:1234. We don't reload the orders
    // page or component so get desired behaviour of not seeing any 
    // flickers or resetting the page.
}

そしてあなたはngOnInitメソッド内でそれを追跡します:

ngOnInit() {
    this.orderId = this.route
        .queryParamMap
        .map(params => params.get('id') || null);
    // orderID is up-to-date with what is saved in database now, or if
    // nothing is saved and hence no id query paramter the orderId variable
    // is simply null.
    // [You can load the order here from its ID if this suits your design]
}

新しい(保存されていない)注文で注文ページに直接移動する必要がある場合は、次の操作を実行できます。

this.router.navigate(['orders']);

または、既存の(保存された)注文の注文ページに直接移動する必要がある場合は、次のようにします。

this.router.navigate(['orders'], { queryParams: { id: '1234' } });

10

angular2のRCxリリースでこれを機能させるのに大きな問題がありました。Locationパッケージが移動し、constructor()内でlocation.go()を実行しても機能しません。ライフサイクルのngOnInit()以降である必要があります。ここにいくつかのサンプルコードがあります:

import {OnInit} from '@angular/core';
import {Location} from '@angular/common';

@Component({
  selector: 'example-component',
  templateUrl: 'xxx.html'
})
export class ExampleComponent implements OnInit
{
  constructor( private location: Location )
  {}

  ngOnInit()
  {    
    this.location.go( '/example;example_param=917' );
  }
}

問題に関する角度のあるリソースは次のとおりです:https : //angular.io/docs/ts/latest/api/common/index/Location-class.html https://angular.io/docs/ts/latest/api/ common / index / LocationStrategy-class.html


7

私はそれを取得するためにこの方法を使用します:

const queryParamsObj = {foo: 1, bar: 2, andThis: 'text'};

this.location.replaceState(
  this.router.createUrlTree(
    [this.locationStrategy.path().split('?')[0]], // Get uri
    {queryParams: queryParamsObj} // Pass all parameters inside queryParamsObj
  ).toString()
);

-編集-

これについては、もう少し情報を追加する必要があると思います。

this.location.replaceState()アプリケーションのルーターを使用する場合は更新されないため、後でルーター情報を使用する場合、ブラウザーではこれは等しくありません。たとえば、を使用localizeServiceして言語を変更した場合、言語を切り替えた後、アプリケーションをで変更する前の最後のURLに戻しますthis.location.replaceState()

この動作を望まない場合は、次のような別の方法でURLを更新できます。

this.router.navigate(
  [this.locationStrategy.path().split('?')[0]],
  {queryParams: queryParamsObj}
);

このオプションでは、ブラウザも更新URLされませんが、変更はRouterアプリケーションに注入されるため、言語を切り替えるときにのような問題は発生しませんthis.location.replaceState()

もちろん、必要に応じて方法を選択できます。1つ目はURL、ブラウザーでの変更以上にアプリケーションを使用しないため、より軽量です。


3

私にとっては、実際には両方のAngular 4.4.5との組み合わせでした。

router.navigateを使用すると、realtiveTo:activatedRouteの部分を尊重しないため、URLが破壊され続けました。

私は次のようになりました:

this._location.go(this._router.createUrlTree([this._router.url], { queryParams: { profile: value.id } }).toString())

3

URLを変更する際は、queryParamsHandling: 'merge'属性を使用してください。

this.router.navigate([], {
        queryParams: this.queryParams,
        queryParamsHandling: 'merge',
        replaceUrl: true,
});

3
これにより、現在ルーティングされているコンポーネントがリロードされます
btx
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.