Angular_現在のURLと同じURLをリロードする #399
AngularのRouterLinkに関わる設定です。Angularのデフォルトでは、現在のページに遷移するボタンがある時に、現在のページでもう一度そのボタンをクリックしてもリロードが走りません。しかしアプリケーションによっては同じボタンをクリックしてページをリロードしたり、URLを初期化したい場面があると思います。
RouterLinkはいくつか設定がありますが、そのうち1つであるOnSameUrlNavigationでこの問題に対処できます。
OnSameUrlNavigation
OnSameUrlNavigationはユーザーが現在のURLと同じURLに遷移しようとしたときの振る舞いを指定するもので、'reload'または'ignore'という値を取ります。その名の通り、それぞれ再読み込みするか、無視するかを指定します。
このデフォルト値がignoreになっているので、reloadを設定します。
[app-routing.module.ts]
const appRoutes: Routes = [
{
path: '',
component: YourComponent,
pathMatch: 'full'
},
{
path: 'sample/path',
component: SampleComponent,
pathMatch: 'full'
}
]
export const routing: ModuleWithProviders<any> = RouterModule.forRoot(appRoutes, {
scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
preloadingStrategy: PreloadAllModules,
onSameUrlNavigation: 'reload' // ここで設定
});
ただしこれだけでは上手くいきません。
'reload'を設定しても、URL自体は初期化されるものの、コンポーネント自体は再利用されてしまいリロードされないためです。これはAngularのRouterが、ページ読込の効率を向上させるためにデフォルトで再利用を試みることに起因しています。
これを解決するための方法が以下です。
routeReuseStrategy.shouldReuseRoute()をfalseにする
RouteReuseStrategy の shouldReuseRoute メソッドを直接オーバーライドすることで、コンポーネントを再利用せずリロードするようになります。
これをrouterを扱うコンポーネントに仕込めばOKです。
typescriptCopy codeimport { Router } from '@angular/router';
export class AppComponent {
constructor(private router: Router) {}
constructor(private router: Router) {
// すべてのルートの再利用を無効にする
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
}
ただしこの場合すべてのルートで再利用が無効化されるので、それが適切かどうかはアプリケーションの要件に応じて判断する必要があります。
特定のルートだけでこの振る舞いを適用したい場合は、shouldReuseRoute メソッド内で適切な条件を指定することになります。また、その他の RouteReuseStrategy メソッド (shouldDetach, store, shouldAttach, retrieve) のデフォルトの挙動が影響を受けることはありません。
また、これらの設定はクリック時に呼び出す関数に仕込むこともできます。
clickComponentReload(){
// リロード時ngOnInit()が呼び出されるように設定
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
this.router.onSameUrlNavigation = 'reload';
// 参考:現在のURLを取得する。
const currentURL = this.router.url;
}
Angularも奥深いですね。
ここまでお読みいただきありがとうございました!!