【问题标题】:Generic type 'CanDeactivate<T>' requires 1 type argument(s)通用类型“CanDeactivate<T>”需要 1 个类型参数
【发布时间】:2017-10-23 03:46:06
【问题描述】:

在下面的代码中(《Angular 2 Development with TypeScript》一书中的一个例子):

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 上时,我看到一条警告:

参考这个问题的答案 - 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;
}

但不清楚“TeamComponent”是什么。

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    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,以防您需要访问一些外部信息。如果您只想对此组件使用此保护并且需要获取组件的属性或确认路由器是否应允许导航离开它,这将非常有用。

    【讨论】:

    • 这对我有帮助。谢谢:)
    猜你喜欢
    • 2017-06-05
    • 2018-12-08
    • 2017-01-09
    • 1970-01-01
    • 2017-02-08
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多