Home  >  Q&A  >  body text

Interaction between ngAfterViewInit and Observable in Angular life cycle

<p><strong>enable.service.ts</strong></p> <pre class="brush:php;toolbar:false;">@Injectable({ providedIn: 'root' }) export class EnableService { isEnabled$ = from(this.client.init()).pipe( switchMap(() => this.client.getEnabled()), map(([enabled, isAdmin]) => ({enabled: true, isAdmin: false})), share() ); // 不完全是这样,但是是一种返回enable和isAdmin的observable constructor( // 一些构造函数 ) {} }</pre> <p><strong>main.component.ts</strong></p> <pre class="brush:php;toolbar:false;">export class MainComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild('mymap') containerRef: ElementRef<HTMLDivElement>; isAdmin: boolean = false; isEnable: boolean = false; constructor( private enableService: EnableService, ) { this.enableService.isEnabled$.subscribe(res => {this.enable = res.enabled; this.isAdmin = res.isAdmin}); } async ngAfterViewInit(): Promise<void> { // HACK: 需要等待enableService订阅获取实际值,否则containerRef #mymap是否存在将无法确定 await new 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>目前这是一个可工作的代码,使用了1秒的延迟hack在ngAfterViewInit中。问题是如果enableService需要多半秒的时间,它将会出错。</p> <p>有没有办法确保ngAfterViewInit在enableService获取值之后执行?</p> <p>或者有没有更好的方法,不用使用那1秒的延迟。如果我将isEnable的初始值设为false,然后最终变为true,会导致问题,同样,如果它一开始就是true,最终还是true,也会导致错误。我尝试将observable的订阅从构造函数移到ngOnInit中,也不起作用。</p>
P粉131455722P粉131455722453 days ago472

reply all(1)I'll reply

  • P粉026665919

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

    Is it useful to try this?

    ts

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

    html

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

    reply
    0
  • Cancelreply