【问题标题】:Get observable return value without subscribing in calling class无需订阅调用类即可获取可观察的返回值
【发布时间】:2020-03-02 21:28:20
【问题描述】:

在 TypeScript / Angular 中,您通常会调用一个返回可观察对象的函数并在组件中订阅它,如下所示:

this.productsService.getProduct().subscribe((product) => { this.product = product });

当代码在管理数据的类中运行时这很好,但我认为这不应该在组件中处理。我可能错了,但我认为组件的工作应该是请求和显示数据而不处理如何检索数据。

在 Angular 模板中,您可以这样做来订阅并显示可观察对象的结果:

<h1>{{ product.title | async }}</h1>

是否可以在组件类中有这样的东西?我的组件显示一个表单并在输入后检查日期是否有效。提交表单被阻止,直到值有效并且我想将它背后的所有逻辑保留在应该订阅 AJAX 调用的服务中,组件只检查它是否有一个有效的日期。

 class FormComponent {
    datechangeCallback(date) {
        this.dateIsValid$ = this.dateService.checkDate(date);
    }

    submit() {
        if (this.dateIsValid$ === true) {
            // handle form submission...
        }
    }
}

【问题讨论】:

  • 你为什么不喜欢可观察/订阅?您真的希望您的代码阻止对 checkDate 的可能长时间运行的调用吗?如果响应中涉及数据处理,那么您仍然可以将其放入包装在您自己的 Observable 中的服务中。这是像 JS 这样的单线程语言的工作方式,所以我建议熟悉 Observables,它肯定比过去的回调更简洁。
  • 嗨。我的问题不在于订阅 observable,而在于订阅和处理组件中的响应。我添加了很多冗余代码,使其可读性降低。这就是模板中存在异步管道的原因,可惜它在组件类中不存在。

标签: javascript angular typescript rxjs


【解决方案1】:

您可以将 rxjs Observables 转换为 ES6 Promises,然后使用 async-await 语法来获取无需订阅 observable 的数据。

服务:

export class DateService {
  constructor(private http: HttpClient) {}

  async isDateValid(date): Promise<boolean> {
    let data = await this.http.post(url, date, httpOptions).toPromise();
    let isValid: boolean;
    // perform your validation and logic below and store the result in isValid variable
    return isValid;
  }
}

组件:

class FormComponent {
    async datechangeCallback(date) {
        this.dateIsValid = await this.dateService.isDateValid(date);
    }

    submit() {
        if (this.dateIsValid) {
            // handle form submission...
        }
    }
}

附注:

如果这是一个简单的 HTTP 请求,它在接收到一个值时完成,那么使用 Promises 不会有什么坏处。但是如果这个 observable 产生了一些连续的值流,那么使用 Promises 并不是最好的解决方案,你必须恢复到 rxjs observables。

【讨论】:

  • 我认为,这就是@Sodium 的意思,同时提出问题。但同时现在大多数情况下首选的方式是 Observables。
  • @Andris 我同意。更新了答案。
  • 嗨,在这种情况下,它是一个简单的 AJAX 调用,在输入更改时被调用。在我看来,尽管组件中的代码仍然太多,但这仍然有效。但是我如何在服务端处理这个问题?这是一个 http 调用(返回 this.http.post(...))。谢谢。
  • 编辑:Oups 对不起,我的服务中的函数仍然有 aync 从我的试验和错误中,它现在可以工作了,谢谢。
  • @Sodium 您能做的最好的事情是将toPromise() 调用和您的逻辑移至服务方法。更新了答案以显示它。
猜你喜欢
  • 1970-01-01
  • 2019-11-12
  • 2020-04-05
  • 2017-06-21
  • 1970-01-01
  • 2017-05-13
  • 2017-10-06
  • 2020-06-23
  • 1970-01-01
相关资源
最近更新 更多