【问题标题】:What is the proper way to return from within an angular subscription?从角度订阅中返回的正确方法是什么?
【发布时间】:2019-03-01 12:57:54
【问题描述】:

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

环境

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

问题

我正在使用角度材质库的 mat-dialog 组件,并订阅从 afterClosed() 返回的 observable。在该订阅中,我有一个简单的 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

}

问题

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

【问题讨论】:

  • 您应该将数据分配给您的组件属性之一 --> this.yourVarName = data

标签: angular typescript rxjs observable


【解决方案1】:

实际上,您的代码有点损坏,这不仅仅是关于良好的编程实践。

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

这是 JavaScript 的核心概念,在 ObservablesPromisesCallback Functions 中应用最为突出。为了使用这种编程语言,了解异步代码执行和 JavaScript 事件循环的工作原理至关重要。

至于您的代码示例,您需要将函数的返回类型更改为 Observable<string> 并将 observable 传递给您的组件类,在那里您可以将其分配给一个属性并让 Angular 处理其余部分。

看起来像这样:

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

【讨论】:

  • 这太棒了,谢谢。这正是我正在寻找的答案类型。我知道我的代码是 hacky 和不正确的。您的解决方案非常合理。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-22
  • 1970-01-01
  • 2018-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
相关资源
最近更新 更多