web-dev-qa-db-ja.com

Angular 4カスタムデコレータ-サービスの挿入

アプリケーションに認証デコレーターを作成したい。

呼び出しは次のように簡単でなければなりません

@RequireAuthentication()
@HostListener('click', ['$event']) onClick(event: Event) {
....
}

私が知っているように、デコレータは機能することができるだけなので、他のいくつかのファイルでは

export function RequireAuthentication() {
    if (!userService.isAuthenticated) {
        navigationService.goToLogin();
        return;
    }
}

この場合、userServiceとnavigationServiceを適切に初期化する方法に問題があります。これらのサービスには、ユーザーが認証されているかどうかを確認してログイン画面を表示するためのすべてのロジックが含まれているためです。

私はすでに試しました:

  1. サービスの初期化のためにコンストラクター付きのクラスを使用するが、ネストされたメソッドはデコレーターとして使用できない
  2. injectableクラスを使用してサービスを作成するには、このクラスのインスタンスを作成する必要があります。同じ問題が発生します。
  3. moduleWithProvidersアプローチを使用して認証の実装を隠し、デコレータのみを公開しますが、これが正しい方法かどうかはわかりません。

ヒントがあれば役に立ちます。 angular開発者でないか、この問題に取り組む別の方法があるため、私は基本的な何かを見逃している可能性があります。

前もって感謝します!

7
Minja

この答え で説明されているように、フレームワークの慣用的な解決策は、injectorクラスインスタンスプロパティを公開することです。これにより、デコレータ内からアクセスできます。 injectorプロパティの存在は、インターフェイスで保護することもできます。

プロパティデコレータは1回実行され、クラスプロトタイプにはアクセスできますがインスタンスにはアクセスできないため、ngOnOnitメソッドにパッチを適用し、this.injector.get()を使用してパッチを適用したメソッド内の必要なすべてのサービスを取得する必要があります。

代替策は、説明されているように here のように、グローバルインジェクタをいくつかのオブジェクトに公開することです。これは慣用的な解決策ではなく、特定の制限と否定的な結果をもたらすハッキングです。本番環境での使用はお勧めできません。

8
Estus Flask