为什么当 Observable 在类级别初始化时,ngOnInit 中的 RxJS 管道不被执行?

use*_*244 1 observable rxjs ngoninit angular

ngOnInit当 Observable 在类属性声明级别初始化时,为什么当异步管道解开 Observable 时管道没有被触发?

我知道我可以自己进行初始化,ngOnInit但我只是想更好地了解 RxJS 流的工作原理。我也知道我可以打电话subscribe()过来ngOnInit,但这不是我的本意。

我尝试过添加假加载来“延迟”模板渲染,希望延迟异步管道,但它仍然不起作用。

成分:

export class MyComponent implements OnInit {

  constructor(
    private dataService: DataService
  ) { }

  items$: Observable<Item[]> = this.dataService.getItems();

  ngOnInit(): void {
    this.items$.pipe(
      tap(data => {
        console.log('items', data);     // <--- this doesn't get called
      })
    )
  }

}
Run Code Online (Sandbox Code Playgroud)

模板:

<div *ngFor="let item of items$ | async">{{ item.name }}</div>
Run Code Online (Sandbox Code Playgroud)

Joo*_*rts 5

虽然有关于如何修复它的很好的评论,但我将解释为什么会这样。

tap(或在旧版本的 RxJS 中执行)-> 透明地执行操作或副作用,例如日志记录(如定义所示)。

在你的情况下,你不会.subscribe()看到你的 Observable,这就是为什么你看不到你的“Item”记录在控制台中。你有一些选择。

  1. 使用管道订阅模板的选项| async
  2. 或者在您的组件中使用.subsribe()

使用异步管道

您还可以直接点击可观察对象,不需要订阅/取消订阅,因为这是由| async管道处理的。

<div *ngIf="items$ | async"></div>
Run Code Online (Sandbox Code Playgroud)
  items$: Observable<Item[]> = this.dataService.getItems().pipe(
    tap((data) => {
      console.log('items', data);
    })
  );

  ngOnInit(): void {}
Run Code Online (Sandbox Code Playgroud)

使用 .subscribe()

如果您添加.subscribe()您将开始获取控制台日志。不过,完成后您还需要取消订阅。

    this.items$.pipe(
      tap(data => {
        console.log('items', data);
      })
    ).subscribe();
Run Code Online (Sandbox Code Playgroud)

工作示例:https ://stackblitz.com/edit/angular-ivy-fcp9fz?file=src%2Fapp%2Fapp.component.ts