同じページの場合、ルーターナビゲートはngOnInitを呼び出しません


89

router.navigateいくつかのクエリ文字列パラメータを使用して同じページを呼び出しています。この場合、ngOnInit()は呼び出さない。デフォルトですか、それとも他に何か追加する必要がありますか?

回答:


139

あなたは注入しActivatedRouteて購読することができますparams

constructor(route:ActivatedRoute) {
  route.params.subscribe(val => {
    // put the code from `ngOnInit` here
  });
}

ルータは、別のルートに移動したときにのみ、コンポーネントを破棄して再作成します。ルートパラメータまたはクエリパラメータのみが更新され、ルートが同じである場合、コンポーネントは破棄および再作成されません。

コンポーネントを強制的に再作成する別の方法は、カスタムの再利用戦略を使用することです。同じURLが異なるパラメータでロードされたときにコンポーネントをリロードしないAngular2router 2.0.0も参照してください(まだそれを実装する方法について利用できる情報はあまりないようです)


1
このサブスクリプションは機能していませんが、initでのみトリガーされます
OsandaWedamulla19年

その場合のコードに固有の@OsandaWedamulla。しかし、より詳細なしで伝えるのは難しい
ギュンターZöchbauer

1
これからも退会する必要はありませんか、それとも自動的に行われますか?
rain 0119年

1
@ rain01経験則として、明示的にサブスクライブした場合は、cpdeで明示的にサブスクライブを解除する必要があります。ルートコンポーネントに上記のコードがある場合、ルートコンポーネントの有効期間は通常、Angularアプリ全体の有効期間と同じであるため、登録解除は冗長です。
ギュンターZöchbauer

このソリューションは、stackoverflow.com / a / 47827668/5284473と組み合わせた場合(またはonSameUrlNavigationをグローバルに設定した場合)に機能します。
S. Roose

105

ルーターでreuseStrategyを調整できます。

constructor(private router: Router) {
    // override the route reuse strategy
    this.router.routeReuseStrategy.shouldReuseRoute = function() {
        return false;
    };
}

2
これにより、ページ上のすべてのコンポーネントのngInitが開始されます。
jforjs

3
ええと、@ Pascal、あなたは私にあなたの答えに賛成票を投じるためだけにSOにログインするように強いました。Angular 6では、次のonSameUrlNavigation: 'reload'ようにconfigオブジェクトにも追加する必要があることを追加しますRouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})。ただし、他のAngularバージョンについては話さないでください。
ヒルディ

1
@ヒルディ、私は同じことをすることを余儀なくされました:) @Pascalに感謝します!ラムダを好む場合は、これを行うことができますthis.router.routeReuseStrategy.shouldReuseRoute =()=> false;
ニック

1
@Swaprks私はrouting.module.tsを作成し、このコンストラクターとしてコードを配置しました
Pascal

2
@Swaprks ..同様の問題があり、上記の回答を試してみたいと思います。しかし、それはこの分野の初心者として私に多くを教えてくれません。コードのどこにこのコードを配置するのですか?コードスニペット(「function()」など)の何かを変更する必要がありますか?routing.module.tsという名前の新しいファイルを作成した場合、他のファイルとどのように相互作用することになっていますか?自動的に作成されるapp-routing.module.tsというファイルもあります。
EDN

24

Angular 9

私は以下を使用しました、そしてそれは働きました。

onButtonClick() {
    this.router.routeReuseStrategy.shouldReuseRoute = function () {
        return false;
    }
    this.router.onSameUrlNavigation = 'reload';
    this.router.navigate('/myroute', { queryParams: { index: 1 } });
}

1
さらに、上記の代わりにラムダも使用します。this.router.routeReuseStrategy.shouldReuseRoute=()=> false;
DhwanilPatel20年

角度8で動作します
のKishan Vaishnav

3
これにより、アプリケーション全体でルーターの動作が変更されますnavigate()か、それともこの特定のユーザーに対して1回だけトリガーされますか?
ハーフリスト

Angular 9で動作します。
IlijaIličić20年

9

おそらくページをリロードする必要がありますか?これが私の解決策です:@NgModuleを変更しました(私の場合はapp-routing.module.tsファイル内):

@NgModule({
  imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })

ここの「ルート」とは何ですか。
DhwanilPatel20年

@DhwanilPatelAngularアプリのルート。たとえば、「constroutes:Routes = [{path: 'crisis-center'、component:CrisisListComponent}、{path: 'heroes'、component:HeroListComponent}、]」angular.io/guide/router#register-router-and -routes
Dionisオロス

1

NgOnInitインスタンスの作成時に1回呼び出されます。同じインスタンスに対して、NgOnInit再度呼び出されることはありません。それを呼び出すには、作成されたインスタンスを破棄する必要があります。


1

ナビゲーション方法については、

this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
this.router.navigate(['/document'], {queryParams: {"search": currentSearch}});

1

私は同じ問題を抱えていました、さらに私は警告を受けました:

did you forget to call `ngZone.run()`

このサイトは最良の解決策を提供しました:

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

...

  constructor(
    private ngZone:NgZone,
    private _router: Router
  ){ }

  redirect(to) {
    // call with ngZone, so that ngOnOnit of component is called
    this.ngZone.run(()=>this._router.navigate([to]));
  }

これに関しては、新しいルートでページを更新するだけで問題を処理する方法を知りたいと思います。その場合、NgZone警告は引き続き表示されます。
Siddhant

0

この問題は、ngOnDestroyを使用してサブスクリプションを終了していないという事実に起因している可能性があります。これがその方法です。

  1. 次のrxjsサブスクリプションのインポートを取り込みます。 import { Subscription } from 'rxjs/Subscription';

  2. OnDestoryをAngularCoreImportに追加します。 import { Component, OnDestroy, OnInit } from '@angular/core';

  3. OnDestoryをエクスポートクラスに追加します。 export class DisplayComponent implements OnInit, OnDestroy {

  4. コンポーネントのサブスクリプションごとに、エクスポートクラスの下にrxjsからSubscriptionの値を使用してオブジェクトプロパティを作成します。 myVariable: Subscription;

  5. サブスクリプションの値をMyVariable:Subscriptionsに設定します。 this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});

  6. 次に、ngOninitのすぐ下にngOnDestory()ライフサイクルフックを配置し、サブスクリプションのサブスクリプション解除ステートメントを挿入します。複数ある場合は、さらに追加します ngOnDestroy() { this.myVariable.unsubscribe(); }


私も自分のngOnDestory代わりに入力し続けますngOnDestroy
;

0

ルート配列内の同じコンポーネントに異なるパスを作成します。

const routes:Routes = [{path: "app"、component:MyComponent}、{path: "app-reload"、component:MyComponent}];

現在のURLが「app」の場合は「app-reload」を使用してナビゲートし、その逆も同様です。


0

これは、このページの最高のアイデアのコレクションと詳細情報です

解決策1-paramsサブスクリプションを使用します。

チュートリアル:https//angular-2-training-book.rangle.io/routing/routeparams#reading-route-parameters

ドキュメント:https//angular.io/api/router/ActivatedRoute#params

param変数を使用する各ルーティングコンポーネントには、次のものが含まれます。

import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs';

// ...

@Component({
    // ...
})
export class MyComponent implements OnInit, OnDestroy {
    paramsSub: Subscription;

    // ...

    constructor(activeRoute: ActivatedRoute) {

    }

    public ngOnInit(): void {
        // ...
        this.paramsSub = this.activeRoute.params.subscribe(val => {
            // Handle param values here
        });

        // ...
    }

    // ...

    public ngOnDestroy(): void {
        // Prevent memory leaks
        this.paramsSub.unsubscribe();
    }
}

このコードのいくつかの一般的な問題は、サブスクリプションが非同期であり、処理が難しい場合があることです。また、ngOnDestroyの購読を解除することを忘れないでください。そうしないと、悪いことが起こる可能性があります。

良いことは、これがこの問題を処理するための最も文書化された一般的な方法であるということです。また、ページにアクセスするたびにテンプレートを破棄して再作成するのではなく、テンプレートを再利用するため、この方法でパフォーマンスが向上します。

解決策2-shouldReuseRoute / onSameUrlNavigation:

ドキュメント:https//angular.io/api/router/ExtraOptions#onSameUrlNavigation

ドキュメント:https//angular.io/api/router/RouteReuseStrategy#shouldReuseRoute

ドキュメント:https//angular.io/api/router/ActivatedRouteSnapshot#params

RouterModule.forRootプロジェクト内の場所を見つけます(通常はapp-routing.module.tsまたはapp.module.tsにあります)。

const routes: Routes = [
   // ...
];

// ...

@NgModule({
    imports: [RouterModule.forRoot(routes, {
        onSameUrlNavigation: 'reload'
    })],
    exports: [RouterModule]
})

次に、AppComponentに以下を追加します。

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

// ...
@Component({
    // ...
})
export class AppComponent implements OnInit {
    constructor(private router: Router) {
    }

    ngOnInit() {
        // Allows for ngOnInit to be called on routing to the same routing Component since we will never reuse a route
        this.router.routeReuseStrategy.shouldReuseRoute = function() {
            return false;
        };

        // ...
    }

    // ...
}

最後に、ルーティングコンポーネントで、次のようなパラメータ変数を処理できるようになりました。

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

// ...

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

    constructor(activeRoute: ActivatedRoute) {

    }

    public ngOnInit(): void {
        // Handle params
        const params = +this.activeRoute.snapshot.params;

        // ...
    }

    // ...
}

このソリューションの一般的な問題は、一般的ではないということです。また、Angularフレームワークのデフォルトの動作を変更しているため、通常は遭遇しない問題に遭遇する可能性があります。

良いことは、すべてのコードが同期していて理解しやすいことです。


-1

ngOnInitにあったコードをngAfterViewInitに移動することを検討してください。後者はルーターナビゲーションで呼び出されるようで、この場合に役立ちます。


3
それは実際には起こりません
nadav 2017年

-7

同じページをルーターでナビゲートし、ngOnInit()を呼び出したい場合は、次のようにします。

this.router.navigate(['category / list'、category])。then(()=> window.location.reload());

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