Angular Rxjs:Observable 不显示在视图上

Angular Rxjs: Observable does not display on view

我有以下代码应该显示音频文件的长度:

ngAfterViewInit() {
    this.duration$ = fromEvent(this.player.nativeElement, 'loadeddata').pipe(
      map((event: any) => {
        return this.convertDuration(event.target.duration);
      }));
  }

但它不会显示在我的 HTML 上,如下所示: <div>{{ duration$ | async }}</div>

这可能是什么问题?我尝试在我的组件中订阅并且这有效:

this.duration$.subscribe(x => console.log(x));

初始化:duration$: Observable<string>;


看了@EliyaCohen 的演示后,我意识到我的代码不起作用的原因是我启用了 ChangeDetectionStrategy.OnPush。我认为我现在的问题是如何在不调用 detectChanges()markForChange() 的情况下触发更改检测,如果可能的话。

这是我的demo

我无法重现你的问题,所以我做了 a simple demo 这可能会有所帮助(不要介意 codesandbox 的错误)。

  1. 我创建了一个 <video> 标签
  2. 我绑定了 video 标签并调用它从 @ViewChild
  3. 导入
  4. ngAfterViewInit 我使用了你所做的确切代码,但没有 convertDuration 因为我不确定它到底做了什么。
  5. 我在 HTML 中订阅了 observable,它起作用了。

如果您可以分享一点您的代码,我也许可以重现它。

我认为它应该这样工作:

@Component({
  /* ... */
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class PlayerComponent implements AfterViewInit {
  duration$: Observable<string>;

  @ViewChild("video", { static: true }) player: ElementRef<HTMLElement>;
  @Input() source: string;

  ngOnInit() {
    this.duration$ = fromEvent(this.player.nativeElement, "loadeddata").pipe(
      map((event: any) => event.target.duration)
    );
  }
}

我正在使用 { static: true },因为 video 元素不依赖于任何条件,例如 ngIf

ngAfterViewInit 的问题在于 异步管道 将在 此生命周期挂钩发生之前 创建其订阅。这意味着在 ngAfterViewInit 被调用时,异步管道已经确定了它的订阅,但是因为这发生在这个钩子之前,所以没有订阅,所以没有什么可以订阅的。