如何在 Angular 中将数据从组件解析到 Guard

How to parse data from component into Guard in Angular

如果用户试图离开他们更改了表单的页面,我想在屏幕上向他们显示提示。到目前为止,我已经创建了一个 Guard,并成功地让它在用户离开此页面时在控制台中记录了一些内容。但是现在,我需要显示一个 Dialog 警告框,他们应该能够取消 'navigation' 或确认他们希望离开。

我的组件中有一个包含表单的方法,用于检查是否对表单进行了更改,现在我只需要实现上述其余部分即可。

这是我的守卫:

import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class RouterGuardGuard implements CanDeactivate<unknown> {
  canDeactivate(
    component: unknown,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    console.log('TESTING');

    return true;
  }

}

我已经在我的 app-routing-module.ts 中为我的组件实现了防护:

  { path: 'users/edit/:id', canDeactivate: [RouterGuardGuard], component: UserEditorComponent },

因此,如果用户对 UserEditorComponent 中的表单进行更改,我需要在导航发生之前显示一个对话框,我已经有了这个对话框的组件,我在不同的地方使用它我的应用程序的一部分。

谢谢

您需要 canDeactivate 方法来确认组件表单的状态。为此,您可以这样做的一种方法是创建一个界面,当在您的组件中实现时 class 将 return 用户决定是离开还是留在组件中。

在你的守卫中,创建一个像这样的接口

 export interface CanComponentDeactivate {
  canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}

使用您刚刚创建的接口代替未知类型:

 export class RouterGuardGuard implements CanDeactivate<CanComponentDeactivate>{...}

..然后在你的 canDeactivate 方法中 return:

  canDeactivate(
    component: CanComponentDeactivate,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return component.canDeactivate();
  }

现在在您的组件中,您需要实现您创建的接口 canComponentDeactivate。因此,在您从界面实现的 canDeactivate 方法中,访问您的表单并检查它是 touched 还是 dirty。如果是这样提示用户和 return promise<boolean>boolean。例如

canDeactivate() {
 if (this.myForm.dirty || this.myForm.touched) {
      return new Promise((resolve) => {
        this.modalService.create({
          content:
            "Your have unsaved changes. Are you sure you want to return?",
          onOk: () => {
            resolve(true);
          },
          onCancel: () => {
            resolve(false);
          },
        });
      });
 }
}