首頁  >  問答  >  主體

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粉131455722453 天前469

全部回覆(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
  • 取消回覆