【问题标题】:"return" asynchronous data using Observables使用 Observables “返回”异步数据
【发布时间】:2018-01-30 02:35:31
【问题描述】:

假设我的 HTML 中有这个:

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

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

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

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

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

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

未捕获的错误:模板解析错误:解析器错误:意外结束 表达式:匹配事件计数:{{(getMatchedEventsCount() | async)?}} 在表达式末尾 [Matched events count: {{(getMatchedEventsCount() | async)?}}] 在 ng:///AppModule/EventsListComponent.html@40:21 (" [错误->]匹配事件计数:{{(getMatchedEventsCount() | async)?}} "): ng:///AppModule/EventsListComponent.html@40:21 解析器错误:条件表达式 (getMatchedEventsCount() | async)? 要求表达式末尾的所有 3 个表达式 [Matched 事件计数:{{(getMatchedEventsCount() | async)?}}] in ng:///AppModule/EventsListComponent.html@40:21 (" [错误->]匹配事件计数:{{(getMatchedEventsCount() | async)?}} "): ng:///AppModule/EventsListComponent.html@40:21

【问题讨论】:

  • 这种方式不能使用?;在? 之后,您必须进行财产访问。尝试删除?
  • 模板解析错误与方法的返回无关。无论返回的结果如何,它都是一样的。与其他编译时间与运行时错误的区别相同..
  • 好的,我会尝试删除 ? 字符
  • 是的,它看起来有效,你能添加一个答案并解释为什么会这样吗?
  • 另外,在你的回答中,如果你能解释如何使用订阅而不是 Obersvable 来加载数据,那也很有用......

标签: angular observable rxjs5


【解决方案1】:

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

您是正确的,您应该从方法中返回 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 会返回 Subscription。然后你必须记住在你的OnDestroy生命周期钩子中从那个订阅中unsubscribe,以防止内存泄漏:

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

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

最后,

我们怎样才能做一些真正异步的事情?

其实很简单。假设您有一个 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>

【讨论】:

    猜你喜欢
    • 2017-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2020-12-02
    相关资源
    最近更新 更多