如果未保存更改,Angular 2/4会阻止用户离开组件

时间:2017-12-04 19:43:00

标签: angular angular-routing angular-router-guards

我有这个界面,我用它来阻止用户离开页面

export interface ComponentCanDeactivate {
  canDeactivate: () => boolean;
}

@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
  canDeactivate(component: ComponentCanDeactivate): boolean {
    return  component.canDeactivate() ?
     //code : //more code
  }
}

在我的一个组件中,我有以下代码

export class DashboardComponent implements ComponentCanDeactivate{
  @HostListener('window:beforeunload')
  canDeactivate(): boolean {
    return !this.isDirty;
  }

我的问题是我的组件 - &gt; PendingChangesGuard中的(component:ComponentCanDeactivate)始终为null,因此我收到错误

无法调用null

的canDeactivate()

我的路由

中也有此设置
 path: 'dashboard',
        canDeactivate: [PendingChangesGuard],
        loadChildren: './views/dashboard/dashboard.module#DashboardModule'

有人能告诉我我做错了什么吗?

3 个答案:

答案 0 :(得分:7)

问题是由延迟加载引起的

而不是在您的应用路由中使用此功能:

path: 'dashboard',
        canDeactivate: [PendingChangesGuard], <-- causing issue
        loadChildren: './views/dashboard/dashboard.module#DashboardModule'

您需要从应用路由中删除canDeactive并将其移至模块路由。

const routes: Routes = [
  {
    path: '',
    component: DashboardComponent,
    canDeactivate: [ PendingChangesGuard ]
  }

答案 1 :(得分:1)

我这样实现

<强>去激活保护功能的service.ts

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

@Injectable()
export class DeactivateGuardService implements  CanDeactivate<CanComponentDeactivate>{

  canDeactivate(component: CanComponentDeactivate) {
    return component.canDeactivate ? component.canDeactivate() : true;
  }
}

<强> Component.ts

checkSave(): Promise<boolean> {
    var prom = new Promise<boolean>((resolve, reject) => {
      //check saved change
        if(saved) resolve(true);
        else reject(false);
    });
    return prom;
  }

  canDeactivate(): Promise<boolean> {

    return this.checkSave().catch(function () {
      return false;
    });
  }

答案 2 :(得分:0)

在PendingChangesGuard中,尝试注入组件本身,而不是接口:

export class PendingChangesGuard implements CanDeactivate<DashboardComponent> {
  constructor() {}
  canDeactivate(component: DashboardComponent): boolean {
  ...
  }

您不能使用Angular DI注入接口,因为接口只是Typescript构造,并且在编译过程中生成的Javascript代码中不存在。

有关详细信息,请查看this SO问题。