Angular 2和TypeScript Promises

pjl*_*b12 26 typescript angular

我正在尝试routerCanDeactivate在我的应用程序中使用该功能.使用它的简单方法如下:

routerCanDeactivate() {
    return confirm('Are you sure you want to leave this screen?');
}
Run Code Online (Sandbox Code Playgroud)

我唯一的问题是它很难看.它只是使用浏览器生成的确认提示.我真的想使用自定义模态,如Bootstrap模式.我有Bootstrap模式根据他们单击的按钮返回true或false值.在routerCanDeactivate我执行可以接受真/假值或解析为真/假的承诺.

以下是具有以下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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当我的TypeScript文件编译时,我在终端中收到以下错误:

error TS2339: Property 'resolve' does not exist on type 'Promise<boolean>'.
error TS2339: Property 'reject' does not exist on type 'Promise<boolean>'.
Run Code Online (Sandbox Code Playgroud)

当我尝试离开组件时,模态启动,但随后组件停用并且不等待承诺解析.

我的问题是尝试计算Promise,以便该routerCanDeactivate方法等待解决的承诺.有没有理由说错误说没有'resolve'财产Promise<boolean>?如果我可以解决这个问题,我必须在routerCanDeactivate方法中返回什么,以便它等待解决/拒绝承诺?

作为参考,这里是DefinitelyTyped Promise定义.那里显然有决心和拒绝功能.

谢谢你的帮助.

UPDATE

这是更新的文件,其中Promise被初始化:

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

handleResponse功能:

handleResponse(res: boolean) {
    console.log('res: ', res);
    this.promise.then(res => {
        console.log('res: ', res);
    });
}
Run Code Online (Sandbox Code Playgroud)

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

更多更新

在做了一些阅读之后,似乎在promise声明中,它设置了resolve值,并且promise无论如何都具有该值.因此,即使稍后我调用该.then方法,它也不会改变它的值,promise并且我无法使其成为真实并切换组件.有没有办法让promise没有默认值,并且必须等到.then调用其方法?

更新功能:

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

handleResponse(res: any) {
    this.promise.then(val => {
        val = res;
    });
}
Run Code Online (Sandbox Code Playgroud)

再次感谢您的帮助.

最后更新

看了很多建议之后,我决定创建一个Deferred课程.它工作得很好,但是当我这样做时deferred.reject(anyType),我在控制台中收到错误:

EXCEPTION: Error: Uncaught (in promise): null
Run Code Online (Sandbox Code Playgroud)

当我传入null,a string或a 时,同样的事情发生boolean.试图catchDeferred课堂上提供一个功能是行不通的.

递延类

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;
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

Ili*_*oly 28

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

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");
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

你正在尝试使用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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)