首页 > 解决方案 > 为什么在带有异步管道的 Angular 模板中未检测到 Subject.next () 发射?

问题描述

有以下代码,我想知道为什么 Subject.next(1)在模板中看不到发射,而BehaviorSubject.next()发射是可见的。

我知道将它包裹在里面可以setTimeout()修复它,但我想理解它。

我似乎Subject.next()同步的,async管道没有接收/标记检查。

@Component({
  selector: 'my-app',
  template: `
    <div>Subj: {{ subj$ | async }}</div>
    <div>BehavSubj: {{ behavSubj$ | async }} </div>
    <div>Interval: {{ interval$ | async }} </div>
  `,
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  subj$ = new Subject<number>();
  behavSubj$ = new BehaviorSubject<number>(1);
  interval$ = interval(1000).pipe(take(100));

  ngOnInit(): void {
    this.subj$.next(1);
    this.behavSubj$.next(2);
  }
}

https://stackblitz.com/edit/angular-ivy-crnfgc?file=src/app/app.component.ts

标签: angularasync-pipe

解决方案


因为时间太早了,没有被发现。替换所有出现的OnInitwithAfterViewInit并且它可以工作。

import { Component, AfterViewInit, OnInit, VERSION } from "@angular/core";
import { BehaviorSubject, interval, Subject } from "rxjs";
import { take } from "rxjs/operators";

@Component({
  selector: "my-app",
  template: `
    <div>Subj: {{ subj$ | async }}</div>
    <div>BehavSubj: {{ behavSubj$ | async }}</div>
    <div>Subj: {{ subj2$ | async }}</div>
    <div>BehavSubj: {{ behavSubj2$ | async }}</div>
    <div>Interval: {{ interval$ | async }}</div>
  `,
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit, AfterViewInit {
  subj$ = new Subject<number>();
  behavSubj$ = new BehaviorSubject<number>(1);
  subj2$ = new Subject<number>();
  behavSubj2$ = new BehaviorSubject<number>(1);
  interval$ = interval(1000).pipe(take(100));

  ngOnInit(): void {
    this.subj$.next(1);
    this.behavSubj$.next(2);
  }

  ngAfterViewInit(): void {
    this.subj2$.next(1);
    this.behavSubj2$.next(2);
  }
}

首先,您必须初始化视图,以便异步管道已被订阅。然后你可以向一个简单的主题发送一个值。行为主体不同。它存储它的最后一个值。您可以先更新一个行为主题,然后再订阅。这也是你必须初始化行为主体但初始化基本主体没有意义的原因。

是一个例子。


推荐阅读