尝试从异步源获取数据时获取无效的异步管道

getting invalid async pipe while trying to get data from a async source

我从异步获取数据 API,在我的前端我有一个网格 Kendo UI,我想将它与这些数据绑定,但在控制台中,我看到无效管道[对象对象]

这是我的服务:

 getEventLog(ip) {
     return this.http.post(this.url_event_log, {}, {params: {id: ip}})
 }

在我的组件中我有:

this.service.getEventLog(id).subscribe(s => {
    this.eventlogs = s;
})

在我的 kendo 网格中,我添加了异步管道:

[data]="eventlogs| async"

您要么在控制器中订阅可观察对象,要么在模板中使用 async 管道。不合并。

方式一:在控制器中订阅

控制器

eventlogs: any;

this.service.getEventLog(id).subscribe(
  s => { this.eventlogs = s; },
  error => { }
);

模板

[data]="eventlogs"

选项 2:async管道

控制器

eventlogs: Observable<any>;

this.eventlogs = this.service.getEventLog(id);

模板

[data]="eventlogs | async"

并且由于您可能不会在控制器中使用 eventLogs 变量,因此最好使用 async 管道,因为它可以解决潜在的内存泄漏问题。

异步管道需要一个流,而不是流的结果。 它避免了您显式订阅流到组件中。

你的情况:

eventlogs$: Observable<any>;

constructor(private service: MyService) {}

ngOnInit() {
  this.eventlogs$ = this.service.getEventLogs(id);
}

在您的模板中:

[data]="eventlogs$ | async"

必须在异步 Observable 上使用 async 管道。 this.service.getEventLog(id).subscribe(...) 行解压你的 Observable this.service.getEventLog(id) 并通过异步回调 s => { this.eventlogs = s}) 将其存储到同步变量 eventlogs 中。所以你最终向异步管道提供了一个同步变量。

解决方案 1:保持异步并提供 Observable

this.eventLogStream = this.service.getEventLog(id)
[data]="eventLogStream | async"

解决方案 2:保持同步并移除 async 管道

this.service.getEventLog(id).subscribe(s=>

  {
   this.eventlogs=s;
   })
[data]="eventlogs"

您应该选择哪种解决方案取决于您最有可能在此代码的其他部分中使用该变量的方式。你会 pipe 并在代码的其他部分转换相同的可观察对象,然后坚持使用解决方案 1 并将其作为异步可观察对象使用吗?如果您只是对出现的数据感兴趣,那么选择解决方案 2 并依靠 Angular 的变化检测在值变化时更新所有内容。

尝试阅读 Observables in Angular 问题非常明显 async pipe 基本上订阅 Observable 和 unsubscribe automatically 这就是为什么推荐的方法是使用异步管道.

在您的案例中不起作用的原因是因为您已经在组件中订阅了 observable。

 /*notice dollar sign at the end of variable that denotes the 
    variable as observable, also variable name should be camelCase.*/
 eventLogs$: Observable<any>;

/*http client always returns observable hence you could return
  that response without subscribing.*/
this.eventLogs$ = this.service.getEventLogs(id);

并且在模板中只使用异步管道,它会订阅流,然后自动取消订阅。

[data]="eventLogs$ | async"