Angular 4+ルートをリロードする調査を行ってきましたが、代わりにコンポーネント内でURLパラメーターの変更をリッスンし、代わりにコンポーネントを再初期化することが望ましい方法のように見えます。
私が抱えている問題は、DRY(繰り返さないでください)アプローチを見つけようとすることです。 AngularJSこれはUIルーターで簡単でした。
ユースケース:
通知がクリックされると、関連するコンテンツに移動する必要があります-これは多くの異なるタイプのコンテンツである可能性があります。
例:_/posts/:id
_または_/groups/:id
_または_/users/:id
_
ユーザーがすでにそのコンテンツを見ている場合、通知のメッセージを反映するためにリロードおよび更新されません。つまり、「John Doeがあなたの投稿にコメントした」(ユーザーがその投稿の古いバージョンを見ている可能性があります)または「Jane DoeがSome Groupへの参加要求を受け入れました」(ユーザーがそのグループのゲストビューを見ている可能性があります)。
ルートが同じであることを検出するときにwindow.location.reload()
を使用することを検討しましたが、それは非常に望ましくない原因です(オーバーヘッドの再初期化、認証チェック、ソケット再接続など)。
どんな提案も大歓迎です!
この場合、ルートは変更されず、パラメーターのみが変更されます。
この問題を解決するには、ActivatedRoute paramsにサブスクライブする必要があります。
export class MyClass implements OnInit {
constructor(private activatedRoute: ActivatedRoute ) {
this.activatedRoute.params.subscribe((params)=>{
console.log('updatedParams', params);
});
}
}
ルートパラメータをサブスクライブして、変更するたびに変更を処理できるようにする必要があります。以下は私のプロジェクトのサンプルコードで、完全に正常に動作しています。
constructor(private router: Router) {
this.route.params.subscribe(params => {
this.initializePage(params['id']);
});
}
initializePage(id:any){
//..Your code
// Consider this as your ngOnInIt() method and initialize everything here.
}
ここで、同じルートのURLでparam値が変更された場合、ページをリロードせず、すべてを再初期化するinitializePage(id)を呼び出しているときに値を変更します。
これがお役に立てば幸いです。
沿って this.router.url
現在のページのURLを取得します。 queryParamesのようにルーターナビゲーションを使用するより。次は、ページネーションのページとしてqueryParamsを渡す例です。同様のアプローチを使用できます。
const url = this.router.url.split('?')[0]; // this will remove previous queryparms
this.router.navigate([url], { queryParams: { page: $event } });
URLに何も変更がなければ、ルートを再ロードする方法はありません。実際、唯一のオプションはwindow.location.reload()
であり、パラメーターの変更をリッスンしています。
2番目のオプションでは、クエリ文字列のid
引数の変更を監視する汎用サービスを作成できます。 IdWatchService
と呼びましょう。これは次のようになります。
@Injectable()
export class IdWatchService {
constructor(private route: ActivatedRoute) {
}
get idChange(): Observable<number | undefined> {
return this.route.queryParams.map(p => p['id'] as number | undefined).distinctUntilChanged();
}
}
次に、このサービスを、変更に対応する必要があるコンポーネント(providers
、PostsComponent
など)のGroupsComponent
のリストに追加できます。そして最後に、それらを同じコンポーネントに注入し、idChange
observableにサブスクライブできます。
@Component({
templateUrl: './posts.component.html',
providers: [
IdWatchService
]
})
export class PostsComponent {
constructor(idWatchService: IdWatchService) {
idWatchService.idChange.subscribe(id => {
// Load data for the new ID and refresh the view
});
}
}
私はangular 2.で同じシナリオ(非常によく似たユースケース)に直面しました。他の回答が言ったように、angularこれを実行します(フレームワークの仮定では、このような場合は、paramsの変更をリッスンするだけで解決されるはずです)。
あなたと同じように、コードを書き直したくなかったので、別のソリューションを使用しました。少しハックがかかっていましたが、変更する必要はほとんどありませんでした。
私が使用した解決策は、ページをリロードする必要がある同じレベルのhirearchyの下にダミーのルートを作成することでした。ダミーのルートでは、DummyComponentを使用しました。これは、次のルート(リロードしたいルート)が何であるかを記述するparamsデータをルートで受け取ります。言及しました)そして、私はそのルートに行くためにナビゲートメソッドで注入されたRounterクラスを使用しました。
このソリューションは、window.reloadを使用するよりもはるかに効率的で、非常に簡単に作成できると思います。 (そのコードにアクセスできないため、そのコード例をコピーすることはできません)
私はDoCheckでこの問題を解決したヘッダーの通知セクションで同じ問題に直面していました
import { Component, DoCheck } from '@angular/core';
クラスでDoCheckインターフェイスを実装します
export class HeaderComponent implements DoCheck {
次に、ngDoCheck()メソッドを使用して、変数値が変更され、通知領域に同じ値が表示されるかどうかを確認します
ngDoCheck() {
// check if values changes
}