在 Angular 11 中完成 Observable 和渲染后如何运行代码?
Posted
技术标签:
【中文标题】在 Angular 11 中完成 Observable 和渲染后如何运行代码?【英文标题】:How to run code after Obsevable AND rendering finished in Angular 11? 【发布时间】:2021-09-11 00:19:56 【问题描述】:在我的 Angular 11 项目中,我有一个 Observable,它改变了视图并在渲染时需要一些时间。
类似这样的:
export class MyComponent implements OnInit
myObservable = of([1, 2, 3]);
constructor()
ngOnInit(): void
this.myObservable.pipe(
// here is some functions
).subscribe();
在ngOnInit
运行后,observable 仍在运行和处理数据。数据到达后,管道更改模板。但这种变化发生在ngAfterViewInit
完成之后。所以我需要一个在管道之后运行的灵魂,并且渲染完成了正在发生的事情,因为管道完成了。
如何在我的 observable 和导致的渲染完成后运行代码(工具提示初始化)?
ngAfterViewChecked
不是一个好的解决方案,因为它总是在视图更改时运行,而且我的工具提示初始化也会更改视图。所以我只想运行一次这个初始化。
有什么解决办法吗?
【问题讨论】:
您在每次可观察到的更改后初始化您的工具提示? 在您依赖数据进行预加载的那一刻,您的整个代码将变为异步,因此请使用订阅处理异步数据。如果你想同步它,你可能想Resolve它 你看过rxjs的startWith操作符吗? @misha130 是的,因为当它发生变化时,视图也会发生变化,消除以前的工具提示装饰元素,我需要使用新的工具提示参数渲染新元素。 @AlekseySolovey 我使用异步数据并使用订阅,但在重新渲染视图后仍然无法运行工具提示初始化。 【参考方案1】:我找到了解决方法:
我将所有代码放入与工具提示相关的单独组件中。实际上它是一个带有信息图标的label
。在这个组件中,我将工具提示初始化代码放入ngAfterViewInit
函数中:
import AfterViewInit, Component, Input from '@angular/core';
import TooltipService from 'src/app/services/tooltip/tooltip.service';
@Component(
selector: 'app-wizzard-label',
templateUrl: './wizzard-label.component.html',
styleUrls: ['./wizzard-label.component.scss'],
)
export class WizzardLabelComponent implements AfterViewInit
@Input() field: any = ;
constructor(
private tooltipService: TooltipService,
)
ngAfterViewInit(): void
this.tooltipService.init();
现在当 observable 完成时,让我的微调器消失并显示这个组件。 ngAfterViewInit
做自己的工作,一切正常。
【讨论】:
【参考方案2】:您可以使用 timout 函数作为解决方法,页面将在管道后加载并在一秒钟后执行您的代码,您可以将其减少到不到一秒钟,您可以通过尝试确定它:
export class MyComponent implements OnInit
myObservable = of([1, 2, 3]);
constructor()
ngOnInit(): void
this.myObservable.pipe(
setTimeout( ()=>
// your code here
, 1000)
).subscribe();
【讨论】:
setTimeout 不是一个好的解决方案,因为我们无法预测这个过程需要多长时间。也许 1 秒太少,也许太多。而且显然没有反应......【参考方案3】:您可以使用async
管道轻松处理来自 Observables 的数据,如果您需要使用 RxJS pipe
函数,您可以将生成的 Observable 保存到一个新变量中,然后在其上使用 async
管道.
查看this stackblitz example
否则,如果管道中的副作用非常复杂,您可以使用 ChangeDetectorRef
手动触发 Angular 更改检测。
查看here 的文档。
【讨论】:
以上是关于在 Angular 11 中完成 Observable 和渲染后如何运行代码?的主要内容,如果未能解决你的问题,请参考以下文章
在 socket.io-client 中调用 IO 时出错,角度 8
for 循环在 Angular 中的 Observable 之前完成