通用类型&#39; CanDeactivate <t>&#39;需要1个类型的参数

时间:2017-05-23 09:14:19

标签: angular typescript

在下面的代码中(本书#34;使用TypeScript和#34进行Angular 2开发的示例):

import {CanDeactivate, Router} from "@angular/router";
import {Injectable} from "@angular/core";

@Injectable()
export class UnsavedChangesGuard implements CanDeactivate{

    constructor(private _router:Router){}

    canDeactivate(){
        return window.confirm("You have unsaved changes. Still want to leave?");

    }
}

当我将鼠标悬停在WebStorm中的CanDeactivate上时,我看到一个警告:

enter image description here

参考此问题的答案 - Generic type 'Observable<T>' requires 1 type argument - 以下更改会删除警告:

export class UnsavedChangesGuard implements CanDeactivate<any>{

然而,我想知道如何找出CanDeactivate需要的实际论点

编辑:看@ angular / router / src / interfaces.d.ts,我们可以看到以下内容:

/**
 * @whatItDoes Indicates that a class can implement to be a guard deciding if a route can be
 * deactivated.
 *
 * @howToUse
 *
 * ```
 * class UserToken {}
 * class Permissions {
 *   canDeactivate(user: UserToken, id: string): boolean {
 *     return true;
 *   }
 * }
 *
 * @Injectable()
 * class CanDeactivateTeam implements CanDeactivate<TeamComponent> {
 *   constructor(private permissions: Permissions, private currentUser: UserToken) {}
 *
 *   canDeactivate(
 *     component: TeamComponent,
 *     route: ActivatedRouteSnapshot,
 *     state: RouterStateSnapshot
 *   ): Observable<boolean>|Promise<boolean>|boolean {
 *     return this.permissions.canDeactivate(this.currentUser, route.params.id);
 *   }
 * }
 *
 * @NgModule({
 *   imports: [
 *     RouterModule.forRoot([
 *       {
 *         path: 'team/:id',
 *         component: TeamCmp,
 *         canDeactivate: [CanDeactivateTeam]
 *       }
 *     ])
 *   ],
 *   providers: [CanDeactivateTeam, UserToken, Permissions]
 * })
 * class AppModule {}
 * ```
 *
 * You can also provide a function with the same signature instead of the class:
 *
 * ```
 * @NgModule({
 *   imports: [
 *     RouterModule.forRoot([
 *       {
 *         path: 'team/:id',
 *         component: TeamCmp,
 *         canActivate: ['canDeactivateTeam']
 *       }
 *     ])
 *   ],
 *   providers: [
 *     {
 *       provide: 'canDeactivateTeam',
 *       useValue: (route: ActivatedRouteSnapshot, state: RouterStateSnapshot) => true
 *     }
 *   ]
 * })
 * class AppModule {}
 * ```
 *
 * @stable
 */
export interface CanDeactivate<T> {
    canDeactivate(component: T, route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean;
}

但不清楚是什么&#34; TeamComponent&#34;是

1 个答案:

答案 0 :(得分:5)

API文档提供了页面底部源代码的链接。

CanDeactivate interface使用泛型来键入第一个canDeactivate参数(已停用的组件):

export interface CanDeactivate<T> {
  canDeactivate(
      component: T, currentRoute: ActivatedRouteSnapshot, currentState: RouterStateSnapshot,
      nextState?: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean;
}

this guide所示,使用已停用的组件实例作为参数调用canDeactivate

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

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

component.canDeactivate只是组件类中同名的方法,它不一定必须被称为canDeactivate甚至存在。 CanComponentDeactivate只是用户定义的接口,它为canDeactivate组件方法提供了约定。

这允许在停用期间与组件交互,

  

canDeactivate()方法为您提供组件的当前实例,当前ActivatedRoute和RouterStateSnapshot,以防您需要访问某些外部信息。如果您只想将此保护用于此组件并且需要获取组件的属性或确认路由器是否允许远离它的导航,这将非常有用。