首页  >  问答  >  正文

Angular生命周期中ngAfterViewInit与Observable之间的互动

<p><strong>enable.service.ts</strong></p>
@Injectable({
  提供于:'root'
})
导出类EnableService {
  isEnabled$ = from(this.client.init()).pipe(
    switchMap(() => this.client.getEnabled()),
    地图(([启用,isAdmin])=>({启用:true,isAdmin:false})),
    分享()
  ); // 不完全是这样,但是是一种返回enable和isAdmin的observable

  构造函数(
    //构造一些函数
  ){}
}</pre>
<p><strong>main.component.ts</strong></p>
<pre class="brush:php;toolbar:false;">导出类 MainComponent 实现 OnInit、AfterViewInit、OnDestroy {
  @ViewChild('mymap') containerRef: ElementRef;

  isAdmin: 布尔值 = false;
  isEnable: 布尔值 = false;

  构造函数(
    私有enableService:EnableService,
  ){
    this.enableService.isEnabled$.subscribe(res => {this.enable = res.enabled; this.isAdmin = res.isAdmin});
  }

  async ngAfterViewInit(): Promise; {
    // HACK: 等待enableService订阅获取实际值,否则containerRef #mymap是否存在将无法确定
    等待新的 Promise(resolve => setTimeout(resolve, 1000));

    // 必须存在地图才能正确隐藏/删除
    if (this.containerRef) {
      // 一些第三方sdk初始化只有在containerRef存在时才执行
    }
  }</pre>
<p><strong>main.component.html</strong></p>
<pre class="brush:php;toolbar:false;"><div #mymap *ngIf="!isEnable || isAdmin"></div></pre>
<p>目前这是一个可以工作的代码,在ngAfterViewInit中使用了1秒的延迟hack。问题是如果enableService需要多半秒的时间,它就会出错。</p>
<p>有没有办法确保ngAfterViewInit在enableService获取值之后执行?</p>
<p>或者没有更好的方法,不用使用那1秒的延迟。如果我将isEnable的初始值设为false,然后最终设为true,会导致问题,同样,如果它一开始就是true,还是最终正确,同时导致错误。我尝试将可观察的订阅从构造函数移到 ngOnInit 中,也失效。</p>
P粉131455722P粉131455722404 天前436

全部回复(1)我来回复

  • P粉026665919

    P粉0266659192023-08-17 09:14:04

    试试这个有用吗?

    ts

    get isEnabled$() {
        return this.enableService.isEnabled$;
    }

    html

    <div #mymap *ngIf="!(isEnabled$ | async).isEnable || (isEnabled$ | async).isAdmin"></div>

    回复
    0
  • 取消回复