Angular CDKオーバーレイモジュール:CanDeactivateGuardはカスタムモーダルを起動する必要があります

フメン

更新:

以下の@BlindDespairの回答に基づいてリファクタリングしました。現在、AngularCDKのオーバーレイモジュールを使用しています。Guardのコードは次のとおりです。

@Injectable({
  providedIn: 'root',
})
export class PendingChangesGuard
  implements CanDeactivate<ComponentCanDeactivate> {
  content = 'A simple string content modal overlay';
  constructor(private overlayService: OverlayService) {}

  canDeactivate(
    component: ComponentCanDeactivate
  ): boolean | Observable<boolean> {
    return component.canDeactivate()
      ? true
      : this.openConfirmDialog(this.content);
  }

  openConfirmDialog(content: TemplateRef<any> | ComponentType<any> | 
string) {
    const ref = this.overlayService.open(this.content, null);

    return ref.afterClosed$.subscribe((res) => {});
  }
}

問題は、この行がサブスクリプションを返していることであり、ガードはブール値またはObservableのいずれかを返す必要があります。

 return ref.afterClosed$.subscribe((res) => {});

OverlayServiceクラスは次のとおりです。

@Injectable({
  providedIn: 'root',
})
export class OverlayService {
  constructor(private overlay: Overlay, private injector: Injector) {}

  open<R = any, T = any>(
    content: string | TemplateRef<any> | Type<any>,
    data: T
  ): RaOverlayRef<R> {
    const configs = new OverlayConfig({
      hasBackdrop: true,
      panelClass: ['modal', 'is-active'],
      backdropClass: 'modal-background',
    });

    const overlayRef = this.overlay.create(configs);

    const myOverlayRef = new RaOverlayRef<R, T>(overlayRef, content, 
data);

    const injector = this.createInjector(myOverlayRef, this.injector);
    overlayRef.attach(new ComponentPortal(OverlayComponent, null, 
injector));

    return myOverlayRef;
  }

  createInjector(ref: RaOverlayRef, inj: Injector) {
    const injectorTokens = new WeakMap([[RaOverlayRef, ref]]);
    return new PortalInjector(inj, injectorTokens);
  }
}

そして、これがRaOverlayクラスです。

export interface OverlayCloseEvent<R> {
  type: 'backdropClick' | 'close';
  data: R;
}

// R = Response Data Type, T = Data passed to Modal Type
export class RaOverlayRef<R = any, T = any> {
  afterClosed$ = new Subject<OverlayCloseEvent<R>>();

  constructor(
    public overlay: OverlayRef,
    public content: string | TemplateRef<any> | Type<any>,
    public data: T // pass data to modal i.e. FormData
  ) {
    overlay.backdropClick().subscribe(() => 
this._close('backdropClick', null));
  }

  close(data?: R) {
    this._close('close', data);
  }

  private _close(type: 'backdropClick' | 'close', data: R) {
    this.overlay.dispose();
    this.afterClosed$.next({
      type,
      data,
    });

    this.afterClosed$.complete();
  }
}

openConfirmDialog()リファクタリングして必要なものを返す方法に関するヒントはありますか?

盲目の絶望

モーダルを開くだけでは結果を定義できないため、そのガードでブール値を返すことはできません。ユーザー入力を待つcanDeactivate必要があります。つまり、ガードはまたはを返すPromise必要がありObservableます。残念ながら、現在のモーダルダイアログは単純すぎて、そのユースケースをサポートできません。基本的には、次のような.afterClosed()ものがPromise<boolean>必要です。またはObservable<boolean>、ユーザーが[はい/いいえ]をクリックしたときに、プロミスを解決するか、サブジェクトに値を出力して完了します。そうすれば.afterClosed()、ガードからの結果を簡単に返すことができます。ただし、そのためにサービスとモーダルをリファクタリングする必要があります。もちろん、あなたは持つことができますafterClosed()モーダルコンポーネントのメソッドとしてですが、そのすべてのメソッドをガードやそれを使用DialogRefするものに公開したくないので、公開したいものだけを公開するを導入することをお勧めします。しかし、これがすでに解決されているのに、なぜ車輪の再発明をするのでしょうか。@angular/cdk非常にスマートなモーダルダイアログを少ない労力で作成するために使用できる、と呼ばれる驚くべき角度モジュールがあります。この記事を確認できます

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

AngularモジュールはangularJS自体と同じバージョンである必要があります

分類Dev

どのモジュールでAngularディレクティブを宣言する必要がありますか?

分類Dev

Angularクライアントはユーザーロールをローカルストレージに保存する必要がありますか?

分類Dev

モジュールに見つからないエラーを修正する必要があります-Angular

分類Dev

Angularルーティングモジュールのルートにコールバック関数をアタッチする方法はありますか?

分類Dev

Angular 7 CDKポータル:エラー接続するポータルを提供する必要があります

分類Dev

Angular2サービスのプロバイダーがありません-外部モジュール

分類Dev

Angular uiルーター-ビューを期待どおりに更新するには、2回クリックする必要があります(デモ付き)

分類Dev

Angularのアプリモジュールにすべての機能モジュールを含める必要がありますか?

分類Dev

AngularJSはカスタムサービスでAngularモジュールを使用します

分類Dev

Angularモジュールの使用方法は?(NullInjectorError:ルーターのプロバイダーがありません)

分類Dev

AngularJSでデコレータを使用する場合のように、Angularコンポーネントをカスタマーモジュールのコンポーネントに置き換える方法はありますか?

分類Dev

Angularインストールアプリモジュールはローカルユーザーフォルダーを検索します

分類Dev

Angular2 +アプリのすべてのコンポーネント/モジュールで「ルーターのプロバイダーがありません」というエラーが表示されるようになりました

分類Dev

Angular 5CLIインポート/カスタムノードモジュールが必要

分類Dev

ルートが変更されたときにAngular UIブートストラップモーダルを自動的に閉じる方法はありますか?

分類Dev

Angularでは、ビューページからアイテムを削除する必要がありますが、Firebaseデータベースからは削除する必要はありません。これについて何か提案はありますか?

分類Dev

Angular 6/7カスタムライブラリを使用するとエラーがスローされますTS2397:モジュール '*'が見つかりません

分類Dev

Angularインポートは、あるモジュールではうまく機能しますが、別のモジュールでは機能しません

分類Dev

Angular5ルーターモジュールChildrenOutletContextsのプロバイダーはありません!エラー

分類Dev

遅延ロードされたモジュールがcommonModuleをインポートする必要があるのはなぜですか?Angular 2

分類Dev

Angular 4にカスタムモジュールをインポートするにはどうすればよいですか?

分類Dev

Angular 2ではどのタイプのフォルダー構造を使用する必要がありますか?

分類Dev

コンポーネントまたはモジュールをangular2のモジュールにランタイムロードします

分類Dev

Angular7はメニューを使用してルートをアクティブにしますが、ルートをコピーして貼り付けると、何があってもホームページにリダイレクトされます

分類Dev

クラスはAngularモジュールではありません-ローカルでビルドされたAngularライブラリをインポートする場合のIntelliJ / Webstormでのみ

分類Dev

Angularがカスタムモジュールを見つけることができません

分類Dev

Angularサービスモジュールはまだ必要ですか?

分類Dev

Angular 4+アプリのコンポーネントごとにモジュールを作成する必要がありますか?

Related 関連記事

  1. 1

    AngularモジュールはangularJS自体と同じバージョンである必要があります

  2. 2

    どのモジュールでAngularディレクティブを宣言する必要がありますか?

  3. 3

    Angularクライアントはユーザーロールをローカルストレージに保存する必要がありますか?

  4. 4

    モジュールに見つからないエラーを修正する必要があります-Angular

  5. 5

    Angularルーティングモジュールのルートにコールバック関数をアタッチする方法はありますか?

  6. 6

    Angular 7 CDKポータル:エラー接続するポータルを提供する必要があります

  7. 7

    Angular2サービスのプロバイダーがありません-外部モジュール

  8. 8

    Angular uiルーター-ビューを期待どおりに更新するには、2回クリックする必要があります(デモ付き)

  9. 9

    Angularのアプリモジュールにすべての機能モジュールを含める必要がありますか?

  10. 10

    AngularJSはカスタムサービスでAngularモジュールを使用します

  11. 11

    Angularモジュールの使用方法は?(NullInjectorError:ルーターのプロバイダーがありません)

  12. 12

    AngularJSでデコレータを使用する場合のように、Angularコンポーネントをカスタマーモジュールのコンポーネントに置き換える方法はありますか?

  13. 13

    Angularインストールアプリモジュールはローカルユーザーフォルダーを検索します

  14. 14

    Angular2 +アプリのすべてのコンポーネント/モジュールで「ルーターのプロバイダーがありません」というエラーが表示されるようになりました

  15. 15

    Angular 5CLIインポート/カスタムノードモジュールが必要

  16. 16

    ルートが変更されたときにAngular UIブートストラップモーダルを自動的に閉じる方法はありますか?

  17. 17

    Angularでは、ビューページからアイテムを削除する必要がありますが、Firebaseデータベースからは削除する必要はありません。これについて何か提案はありますか?

  18. 18

    Angular 6/7カスタムライブラリを使用するとエラーがスローされますTS2397:モジュール '*'が見つかりません

  19. 19

    Angularインポートは、あるモジュールではうまく機能しますが、別のモジュールでは機能しません

  20. 20

    Angular5ルーターモジュールChildrenOutletContextsのプロバイダーはありません!エラー

  21. 21

    遅延ロードされたモジュールがcommonModuleをインポートする必要があるのはなぜですか?Angular 2

  22. 22

    Angular 4にカスタムモジュールをインポートするにはどうすればよいですか?

  23. 23

    Angular 2ではどのタイプのフォルダー構造を使用する必要がありますか?

  24. 24

    コンポーネントまたはモジュールをangular2のモジュールにランタイムロードします

  25. 25

    Angular7はメニューを使用してルートをアクティブにしますが、ルートをコピーして貼り付けると、何があってもホームページにリダイレクトされます

  26. 26

    クラスはAngularモジュールではありません-ローカルでビルドされたAngularライブラリをインポートする場合のIntelliJ / Webstormでのみ

  27. 27

    Angularがカスタムモジュールを見つけることができません

  28. 28

    Angularサービスモジュールはまだ必要ですか?

  29. 29

    Angular 4+アプリのコンポーネントごとにモジュールを作成する必要がありますか?

ホットタグ

アーカイブ