Angular生命周期中ngAfterViewInit与Observable之间的互动
P粉131455722
P粉131455722 2023-08-16 19:03:09
[JavaScript讨论组]

enable.service.ts

@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(
    // 一些构造函数
  ) {}
}

main.component.ts

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存在时才执行
    }
  }

main.component.html

<div #mymap *ngIf="!isEnable || isAdmin"></div>

目前这是一个可工作的代码,使用了1秒的延迟hack在ngAfterViewInit中。问题是如果enableService需要多半秒的时间,它将会出错。

有没有办法确保ngAfterViewInit在enableService获取值之后执行?

或者有没有更好的方法,不用使用那1秒的延迟。如果我将isEnable的初始值设为false,然后最终变为true,会导致问题,同样,如果它一开始就是true,最终还是true,也会导致错误。我尝试将observable的订阅从构造函数移到ngOnInit中,也不起作用。

P粉131455722
P粉131455722

全部回复(1)
P粉026665919

试试这个有用吗?

ts

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

html

<div #mymap *ngIf="!(isEnabled$ | async).isEnable || (isEnabled$ | async).isAdmin"></div>
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号