从角度订阅中返回的正确方法是什么?

时间:2018-09-25 20:13:27

标签: angular typescript rxjs observable

免责声明:这是一个“良好的编程习惯”问题,而不是“修复我的损坏代码”问题。

环境

Angular 5.2.9,Angular Material 5.2.4,Typescript 2.4.2,Rxjs 5.5.8

问题

我正在使用角度材质库的mat-dialog组件,并订阅afterClosed()返回的可观察对象。在该订阅中,我有一个简单的if语句。如果返回value,则返回value,否则返回null。我的tslint非常适合从异步订阅内部返回。确切的错误是,“ TS2355:声明类型为'void'或'any'的函数都必须返回值。”

代码

private openModal() : string {

    // some setup code

    this.dialog.open(MyModalComponent, configModal)
        .afterClosed()
        .subscribe(( data : string ) => {
            if ( data ) {
                return data;
            } else {
                return null;
            }
        });

    // cant put return here,  this will execute before modal returns data

}

问题

我想为我的函数指定一个返回类型'string',但这意味着我需要从同步函数openModal()中进行实际的返回,而不是在订阅中进行异步代码。我愿意接受所有有关如何改进此代码的建议。谢谢!

1 个答案:

答案 0 :(得分:1)

实际上,您的代码有点坏,这不仅与良好的编程习惯有关。

您正在使用Observable,这会使您的代码变为异步。一旦您的代码是异步的,它就永远不会再变得同步,您必须使用异步类型,直到函数的最后一个使用者为止。在Angular应用程序中,这通常是组件或指令。

这是JavaScript的核心概念,在 Observables Promise Callback Functions 中最为突出。了解异步代码执行和JavaScript事件循环如何与这种编程语言一起工作至关重要。

对于您的代码示例,您需要将函数的返回类型更改为Observable<string>并将可观察对象传递到组件类,在组件类中您可以将其分配给属性并让Angular处理其余部分。 / p>

它看起来像这样:

private openModal() : Observable<string> {

    // some setup code

    return this.dialog.open(MyModalComponent, configModal)
        .afterClosed();
}

然后在您的组件中...

private data: string;

clickSomeButton()  {
    this.openModal().subscribe(data => this.data = data);
}