从 CanDeactivate 守卫访问组件属性

Accessing component properties from CanDeactivate guard

我在一个应用程序中有多个表单,我有一个 CanDeactivate 守卫提示用户确认他们是否要离开页面而不先保存他们编辑的表单。每个带有表单的组件都有一个 hasBeenEdited 函数来检查表单是否已被编辑。由于我只有一个 CanDeactivate 可注入 class 来处理所有这些带有表单的组件,因此我需要访问用户当前路由到的组件的 hasBeenEdited 函数。如何最好地做到这一点?我见过这样的例子,其中守卫 class 中的 canDeactivate 函数被传递了一个组件参数,但我不确定如何传递当前路由的组​​件。

描述 canDeactivate 接口

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

描述守卫

@Injectable()
export class CanDeactivateGuard implements CanDeactivate<CanDeactivateComponent> {
  canDeactivate(component: CanDeactivateComponent) {
    return component.canDeactivate ? component.canDeactivate() : true;
  }
}

描述路线

 path: 'yourPath',     
 canDeactivate: [CanDeactivateGuard],
 component: YourComponent

和组件:

 ...
 class YourComponent implements CanDeactivateComponent {
 ...
   canDeactivate() { 
     ... everything you need to detect if you can leave route: return false, 
       or observable
   }

您可以尝试使用 IEdited 界面:

interface IEdited {
  hasBeenEdited: (): boolean
}

并让您的组件实现它,然后也许这会起作用:

@Injectable()
class CanDeactivateEdited implements CanDeactivate<IEdited> {
  canDeactivate(
    component: IEdited,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState: RouterStateSnapshot
  ): boolean {
    return component.hasBeenEdited();
  }
}

我正在使用 Angular 5,(我不知道这很重要!)但是接受的答案对我来说还不够,我了解到我们需要“使用提供程序在应用程序路由模块中配置守卫@NgModule 装饰器的属性”, 来源:https://www.concretepage.com/angular-2/angular-candeactivate-guard-example

所以除了接受的答案外,我还必须像下面这样在 app-routing.module.ts 中添加提供商:

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[CustomExitGuard]
})