こんばんは。 たーせるです。
ついに@ngrxもバージョン8 になりましたね。
#ngrx のバージョンが上がり、いくつか破壊的な変更が発生している。 むしろなぜ今まで、あの冗長なActionの書き方が許されていたのか。 pic.twitter.com/hS9MKkvRaX
— たーせる (@tercel_s) 2019年6月15日
正直、@ngrxはSingle Page Applicationsにおける状態管理ライブラリとしては永らくvuexの後塵を拝してきた感がありました。 しかし上記のツイートからも判る通り、今回はなかなかどうして本質的なコーディングに集中できるようAPIが洗練されたなぁと思いました。
閑話休題。 今日の記事は、こちらの続きになります。
やりたいこと
Guardの中で、遷移元のパス (URL) に応じて認可の可否を制御したい。 そのために遷移元のパスが何だったのかを調べたい!
もう少しだけ具体的に申しますと、直リンクを禁止したい(必ず特定のページを経由してアクセスさせたい)ような場合に使えるテクニックをご紹介したいと思います。
ソリューション
Angular の RoutesRecognized イベントと、rxjs の pairwise オペレータを使う。
pairwise は、現在の値と前回の値を配列としてまとめて出力するオペレータです。
この前回の値を適当なフィールドに保持しておけば、いざというときどこから来たのかを調べることができます。
import { Injectable } from '@angular/core'; import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router, RoutesRecognized } from '@angular/router'; import { Observable } from 'rxjs'; import { filter, pairwise } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class AppGuard implements CanActivate { private prevUrl: string; // 直前のURLがブチ込まれる constructor(router: Router) { router.events .pipe( filter(e => e instanceof RoutesRecognized), pairwise<RoutesRecognized>()) .subscribe(x => this.prevUrl = x[0].urlAfterRedirects); } canActivate( next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { /* 略 */ } }
フィールド prevUrl
には、前回の URL が格納されます。 ちなみに初回アクセス時には、undefined
が入っています。
制限事項
よそのサイトからアクセスした場合や、F5 (Ctrl + R) で再読み込みした場合、prevUrl
は undefined
になります。
もし、どうしても再読み込みに対応したい場合は、window.performance.navigation が、数値の1
と等しいかどうかを調べることで一応対応できます(ただ、window.performance.navigation
は非推奨APIなので、少なくとも売り物に組み込むべきではないというのが僕の考えです)。
では、また。