"return" 使用 Observables 的异步数据

"return" asynchronous data using Observables

假设我的 HTML:

中有这个
  <div>
    <mat-label>Matched events count: {{(getMatchedEventsCount() | async)?}}</mat-label>
  </div>
  <div>
    <mat-label>Total events count: {{(getTotalEventsCount() | async)?}}</mat-label>
  </div>

我的问题是,我从这些辅助方法中 return(就 Observable 而言)是什么?

  getMatchedEventsCount(){
    return Observable.of(3);
  }

  getTotalEventsCount(){
    return Observable.of(5);
  }

但我的问题是 - 我们怎样才能做一些真正异步的事情?

目前,我遇到了这个 HTML 解析错误:

Uncaught Error: Template parse errors: Parser Error: Unexpected end of expression: Matched events count: {{(getMatchedEventsCount() | async)?}} at the end of the expression [Matched events count: {{(getMatchedEventsCount() | async)?}}] in ng:///AppModule/EventsListComponent.html@40:21 (" [ERROR ->]Matched events count: {{(getMatchedEventsCount() | async)?}} "): ng:///AppModule/EventsListComponent.html@40:21 Parser Error: Conditional expression (getMatchedEventsCount() | async)? requires all 3 expressions at the end of the expression [Matched events count: {{(getMatchedEventsCount() | async)?}}] in ng:///AppModule/EventsListComponent.html@40:21 (" [ERROR ->]Matched events count: {{(getMatchedEventsCount() | async)?}} "): ng:///AppModule/EventsListComponent.html@40:21

我注意到您已经在评论线程中解决了 ? 的问题。 ?(称为 "save navigation operator")在那里不起作用的原因是它防止 属性 中的 nullundefined 路径,这意味着您需要在使用 ? 之后尝试访问 属性。现在你正试图追溯使用它来查看一个对象是null还是undefined,但它只能向前看对象,不能向后看,它需要一个属性来寻找。

你是正确的,你应该从方法中 return 一个 Observable 并将其提供给 async 管道。这里有一些关于 async 管道的文档,只是为了彻底:https://angular.io/api/common/AsyncPipe.

关于您在评论线程中关于如何使用 Subscription 而不是 Observable 加载数据的问题...

您可以使用 subscribe 方法并将数据分配给组件上的 属性,如下所示:

matchedEventsSub: Subscription;
matchedEventsCount: number;

getMatchedEventsCount() {
  this.matchedEventsSub = Observable.of(3).subscribe(value => {
    this.matchedEventsCount = value;
  });
}

请注意 subscribeing 到 Observable return Subscription。然后你必须记住 unsubscribe 从你的 OnDestroy 生命周期钩子中的那个订阅来防止内存泄漏:

ngOnDestroy() {
  if (this.matchedEventsSub) { this.matchedEventsSub.unsubscribe(); }
}

您可以想象,当您在一个组件中有 2、3、10 个订阅时,这会变得很麻烦。这就是 Angular 团队创建 async 管道的原因。

最后,

how can we do something actually asynchronous?

其实很简单。假设您有一个 EventsService 注入到您的组件中:

constructor(private eventsService: EventService) {}

该服务可能会封装一个 Http 请求或其他东西 -- Angular 的 HttpClient 模块使用 Observables 来表示异步数据。您可以使用 EventsService 获取异步事件流,如下所示:

matchedEventsCount$: Observable<number>;

getMatchedEventsCount(): Observable<number> {
  const allEvents$ = this.eventsService.getEvents();
  return allEvents$.map(events => events.length);
}

调用 OnInit 生命周期挂钩中的方法来填充数据:

ngOnInit() {
  this.getMatchedEventsCount();
}

然后将其显示在您的模板中:

<h1>Events: {{ matchedEventsCount$ | async }}</h1>