问题描述
有以下代码,我想知道为什么 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);
}
}
管道没有接收/标记进行检查。
{{1}}
https://stackblitz.com/edit/angular-ivy-crnfgc?file=src/app/app.component.ts
解决方法
它没有被检测到,因为它太早了。用 OnInit
替换所有出现的 AfterViewInit
并且它有效。
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);
}
}
首先你必须初始化视图,以便异步管道已经被订阅。然后您可以向一个简单的主题发送一个值。行为主体不同。它存储它的最后一个值。您可以先更新行为主题,然后再订阅。这也是为什么你必须初始化一个行为主题,而初始化一个基本主题没有意义。
Here 就是一个例子。