首页 新闻 会员 周边 捐助

angular 中如何判断 ngOnInit 是否已执行过

0
悬赏园豆:30 [待解决问题] 浏览: 36次

问题场景是这样的,在 NavigationStart 路由事件订阅函数中开始显示 Spinner,在 ngOnInit 中获取数据进行绑定,然后关闭 Spinner。

点击 tab 首次访问对应的 url 时,先是执行 NavigationStart 订阅函数显示 Spinner,然后执行 ngOnInit 关闭 Spinner,一切正常。

再次点击同样的 tab 访问同样的 url,也希望更新数据并关闭 Spinner,但这时不会执行 ngOnInit,只执行 NavigationStart 订阅函数,结果 Spinner 一直在打转。

引入 NavigationEnd 订阅函数更新数据并关闭 Spinner 解决这个问题,但第一次请求时 NavigationEnd 订阅函数与 ngOnInit 都会执行(NavigationEnd 先于 ngOnInit),造成重复操作。

所以想在 NavigationEnd 订阅函数中判断 ngOnInit 是否已执行过。

dudu的主页 dudu | 高人七级 | 园豆:28244
提问于:2025-01-22 20:23
< > 人人可用的开源BI工具
分享
所有回答(1)
0

在 Angular 中,要判断 ngOnInit 是否已经执行过可以使用一个布尔变量来跟踪它的状态。这个变量在组件初始化时设置为 false,在 ngOnInit 中执行时设置为 true。这样,在 NavigationEnd 中你就可以检测 ngOnInit 是否已经执行过,从而决定是否更新数据和控制 Spinner。

以下是一个简化的实现示例:

import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart, NavigationEnd } from '@angular/router';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
})
export class ExampleComponent implements OnInit {
  private initialized = false; // 追踪 ngOnInit 是否已执行
  private routerSubscription: Subscription;

  constructor(private router: Router) {}

  ngOnInit(): void {
    // 组件初始化,执行数据获取等操作
    this.initialized = true;
    this.loadData();
    this.stopSpinner();
  }

  ngOnDestroy(): void {
    if (this.routerSubscription) {
      this.routerSubscription.unsubscribe();
    }
  }

  private loadData(): void {
    // 数据加载逻辑
    console.log('Loading data...');
  }

  private startSpinner(): void {
    // 开始显示 Spinner
    console.log('Start Spinner');
  }

  private stopSpinner(): void {
    // 停止显示 Spinner
    console.log('Stop Spinner');
  }

  constructor(private router: Router) {
    this.routerSubscription = this.router.events.subscribe(event => {
      if (event instanceof NavigationStart) {
        this.startSpinner();
      }

      if (event instanceof NavigationEnd) {
        // 在 NavigationEnd 中只更新数据和关闭 Spinner 如果 ngOnInit 已执行
        if (this.initialized) {
          this.loadData();
        }
        this.stopSpinner();
      }
    });
  }
}

解释:

  1. initialized 变量

    • 这个布尔变量用于标记 ngOnInit 是否已经执行过。
  2. ngOnInit 方法

    • ngOnInit 中,设置 initializedtrue 并调用 loadData() 来加载数据,同时停止 Spinner。
  3. Router 事件订阅

    • 在构造函数中订阅路由事件,NavigationStart 时显示 Spinner,NavigationEnd 时检查 initialized 状态。只有在 ngOnInit 已执行过的情况下才调用 loadData() 和停止 Spinner。

优点:

  • 通过这种方式,可以有效地处理组件的生命周期和路由变化之间的逻辑。
  • 避免了在重复路由时 Spinner 不关闭的问题,同时也避免了重复加载数据。

如果你想进一步讨论该方案或有其他问题,请告诉我!

Technologyforgood | 园豆:7840 (大侠五级) | 2025-01-23 09:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册
Top