我正在try 对我的应用程序中的一个组件使用routerCanDeactivate函数.使用它的简单方法如下:

routerCanDeactivate() {
    return confirm('Are you sure you want to leave this screen?');
}

我唯一的问题是它很难看.它只使用浏览器生成的确认提示.我真的想使用一个自定义模式,比如 bootstrap 模式.我让 bootstrap 模式根据他们点击的按钮返回真值或假值.我正在实现的routerCanDeactivate可以接受真/假值或解析为真/假的promise .

以下是具有routerCanDeactivate方法的组件的代码:

export class MyComponent implements CanDeactivate {
    private promise: Promise<boolean>;

    routerCanDeactivate() {
        $('#modal').modal('show');
        return this.promise;
    }

    handleRespone(res: boolean) {
        if(res) {
            this.promise.resolve(res);
        } else {
            this.promise.reject(res);
        }
    }
}

当我的TypeScript文件编译时,终端中出现以下错误:

error TS2339: Property 'resolve' does not exist on type 'Promise<boolean>'.
error TS2339: Property 'reject' does not exist on type 'Promise<boolean>'.

当我试图离开组件时,模式启动,但组件停用,不等待promise 解决.

我的问题是试图制定promise ,以便routerCanDeactivate方法等待promise 得到解决.Promise<boolean>上没有'resolve'属性的错误是有原因的吗?如果我能解决这一部分,我必须在routerCanDeactivate方法中返回什么,以便它等待promise 的解决/拒绝?

作为参考,here is the DefinitelyTyped Promise definition.这里显然有一个解决和拒绝功能.

谢谢你的帮助.

UPDATE

以下是更新后的文件,promise 已初始化:

private promise: Promise<boolean> = new Promise(
    ( resolve: (res: boolean)=> void, reject: (res: boolean)=> void) => {
        const res: boolean = false;
        resolve(res);
    }
);

以及handleResponse功能:

handleResponse(res: boolean) {
    console.log('res: ', res);
    this.promise.then(res => {
        console.log('res: ', res);
    });
}

它仍然不能正常工作,但模态显示并等待响应.当你说"是"离开时,它会留在组件上.此外,记录的第一个res是组件返回的正确值,但.then函数中的值与传递给handleResponse函数的值不同.

More Updates

在做了更多的阅读之后,似乎在promise声明中,它设置了resolve值,而promise无论如何都有这个值.所以,即使稍后我调用.then方法,它也不会改变promise的值,我也无法使其变为真并切换组件.有没有办法使promise不具有默认值,并且必须等待调用its .then方法?

更新功能:

private promise: Promise<boolean> = new Promise((resolve, reject) => resolve(false) );

handleResponse(res: any) {
    this.promise.then(val => {
        val = res;
    });
}

再次感谢你的帮助.

Last Update

在考虑了很多建议后,我决定创建一个Deferred类.它运行得很好,但当我执行deferred.reject(anyType)时,控制台中出现了一个错误:

EXCEPTION: Error: Uncaught (in promise): null

当我通过null分、string分或boolean分时,同样的事情也会发生.试图在Deferred类中提供catch函数是行不通的.

Deferred Class

export class Deferred<T> {
    promise: Promise<T>;
    resolve: (value?: T | PromiseLike<T>) => void;
    reject:  (reason?: any) => void;

    constructor() {
        this.promise = new Promise<T>((resolve, reject) => {
            this.resolve = resolve;
            this.reject  = reject;
        });
    }
}

推荐答案

我不熟悉bootstrap模式api,但我希望在创建关闭事件时,会有一种方法以某种方式绑定到关闭事件.

export class MyComponent implements CanDeactivate {

  routerCanDeactivate(): Promise<boolean> {
    let $modal = $('#modal').modal();
    return new Promise<boolean>((resolve, reject) => {
      $modal.on("hidden.bs.modal", result => {
        resolve(result.ok);
      });
      $modal.modal("show");
    });
  }

}

你想用Promise,比如Deferred.如果你想要那种API,那就编写一个Deferred类.

class Deferred<T> {

  promise: Promise<T>;
  resolve: (value?: T | PromiseLike<T>) => void;
  reject:  (reason?: any) => void;

  constructor() {
    this.promise = new Promise<T>((resolve, reject) => {
      this.resolve = resolve;
      this.reject  = reject;
    });
  }
}

export class MyComponent implements CanDeactivate {

    private deferred = new Deferred<boolean>();

    routerCanDeactivate(): Promise<boolean> {
        $("#modal").modal("show");
        return this.deferred.promise;
    }

    handleRespone(res: boolean): void {
        if (res) {
            this.deferred.resolve(res);
        } else {
            this.deferred.reject(res);
        }
    }
}

Typescript相关问答推荐

类型脚本不会推断键的值类型

使用FormArray在Angular中添加排序

如何为ViewContainerRef加载的Angular组件实现CanDeactivate保护?

类型脚本强制泛型类型安全

具有动态键的泛型类型

material 表不渲染任何数据

在TypeScrip的数组中判断模式类型

如何在Type脚本中动态扩展函数的参数类型?

在保留类型的同时进行深层键名转换

NPM使用Vite Reaction应用程序运行预览有效,但我无法将其部署到Netlify

为什么TS2339;TS2339;TS2339:类型A上不存在属性a?

棱角分明-什么是...接口类型<;T>;扩展函数{new(...args:any[]):t;}...卑鄙?

递归生成常量树形 struct 的键控类型

如何在Angular /字体中访问API响应的子元素?

窄SomeType与SomeType[]

JSX.Element';不可分配给类型';ReactNode';React功能HOC

如何使用 AWS CDK 扩展默认 ALB 控制器策略?

带动态键的 TS 功能

使用 fp-ts 时如何使用 TypeScript 序列化任务执行?

为什么我的 Typescript 函数中缺少 void 隐式返回类型?