router.navigate
いくつかのクエリ文字列パラメータを使用して同じページを呼び出しています。この場合、ngOnInit()
は呼び出さない。デフォルトですか、それとも他に何か追加する必要がありますか?
回答:
あなたは注入しActivatedRoute
て購読することができますparams
constructor(route:ActivatedRoute) {
route.params.subscribe(val => {
// put the code from `ngOnInit` here
});
}
ルータは、別のルートに移動したときにのみ、コンポーネントを破棄して再作成します。ルートパラメータまたはクエリパラメータのみが更新され、ルートが同じである場合、コンポーネントは破棄および再作成されません。
コンポーネントを強制的に再作成する別の方法は、カスタムの再利用戦略を使用することです。同じURLが異なるパラメータでロードされたときにコンポーネントをリロードしないAngular2router 2.0.0も参照してください。(まだそれを実装する方法について利用できる情報はあまりないようです)
ルーターでreuseStrategyを調整できます。
constructor(private router: Router) {
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function() {
return false;
};
}
onSameUrlNavigation: 'reload'
ようにconfigオブジェクトにも追加する必要があることを追加しますRouterModule.forRoot(appRoutes, {onSameUrlNavigation: 'reload'})
。ただし、他のAngularバージョンについては話さないでください。
私は以下を使用しました、そしてそれは働きました。
onButtonClick() {
this.router.routeReuseStrategy.shouldReuseRoute = function () {
return false;
}
this.router.onSameUrlNavigation = 'reload';
this.router.navigate('/myroute', { queryParams: { index: 1 } });
}
navigate()
か、それともこの特定のユーザーに対して1回だけトリガーされますか?
おそらくページをリロードする必要がありますか?これが私の解決策です:@NgModuleを変更しました(私の場合はapp-routing.module.tsファイル内):
@NgModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: 'reload'})] })
私は同じ問題を抱えていました、さらに私は警告を受けました:
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]));
}
この問題は、ngOnDestroyを使用してサブスクリプションを終了していないという事実に起因している可能性があります。これがその方法です。
次のrxjsサブスクリプションのインポートを取り込みます。
import { Subscription } from 'rxjs/Subscription';
OnDestoryをAngularCoreImportに追加します。
import { Component, OnDestroy, OnInit } from '@angular/core';
OnDestoryをエクスポートクラスに追加します。
export class DisplayComponent implements OnInit, OnDestroy {
コンポーネントのサブスクリプションごとに、エクスポートクラスの下にrxjsからSubscriptionの値を使用してオブジェクトプロパティを作成します。
myVariable: Subscription;
サブスクリプションの値をMyVariable:Subscriptionsに設定します。
this.myVariable = this.rmanagerService.getRPDoc(books[i].books.id).subscribe(value => {});
次に、ngOninitのすぐ下にngOnDestory()ライフサイクルフックを配置し、サブスクリプションのサブスクリプション解除ステートメントを挿入します。複数ある場合は、さらに追加します
ngOnDestroy() {
this.myVariable.unsubscribe();
}
ngOnDestory
代わりに入力し続けますngOnDestroy
これは、このページの最高のアイデアのコレクションと詳細情報です
解決策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フレームワークのデフォルトの動作を変更しているため、通常は遭遇しない問題に遭遇する可能性があります。
良いことは、すべてのコードが同期していて理解しやすいことです。
ngOnInitにあったコードをngAfterViewInitに移動することを検討してください。後者はルーターナビゲーションで呼び出されるようで、この場合に役立ちます。