Angular语言 - Async管道在ngIf和文本绑定中不会显示第一个发出的值



我有一个简单的组件模板:

<button (click)="emitNextValue()">Next Value</button>
<p *ngIf="text$ | async">
{{ text$ | async }}
</p>

和组件代码:

export class AppComponent {
count = 1;
text$ = new Subject<string>();
emitNextValue(): void {
this.text$.next(`Value ${this.count}`);
this.count += 1;
}
}

可以看到,只有当text$Subjects发出值时,模板中的<p>才会显示。点击"下一个值"按钮将调用主题上的next,因此应该显示段落。

问题是<p>只显示在第二个单击,我认为这是不正确的。

知道我错过了什么,还是这是真正的bug?

Demo在stackblitz上可用。

这就是所谓的"晚订阅者"问题。当传入的Rx值在订阅发生之前到达时,会发生此问题。

如果你从html中删除*ngIf指令,它会正常工作。

<p>
{{ text$ | async }}
</p>

查看更多信息

订阅晚了。通常情况下,您可以通过shareReplay(1)操作符或使用ReplaySubject(1)主题使订阅重播上次事件。但在你的特殊情况下,有一个更好的解决方案

<p *ngIf="text$ | async as text">
{{ text }}
</p>

ngIf允许"store"表达式的结果对于这种情况非常有用

事实上,<p>元素是在第一个事件被通知后才创建的。

因此,在通知第一个事件之后,Dom中就有了元素,因此也有了{{ text$ | async }}。然后,当发生第二次单击时,将通知第二个事件并触发绑定。

如果您将Subject替换为new ReplaySubject<any>(1),您将在第一次单击后显示文本。

原因是ReplaySubject一旦被订阅,就会重播它发出的最后一个值。因此,即使文本绑定发生在通知第一个事件之后,被通知的值也会被主题重放,因此会显示在<p>元素中。

相关内容

  • 没有找到相关文章

最新更新