You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular异步调用问题:updateQuestions调用时机错误致变量异常

解决异步数据加载导致的updateQuestions调用时机问题

核心问题分析

你的代码中setAssessmentData是异步操作,assessmentData.securityControl需要等待接口返回后才能赋值。当前存在两个关键问题:

  1. isAssessmentDataLoading仅在错误回调中更新,成功加载后未重置为false,导致加载状态始终异常。
  2. 当isControlSecurityComplete为true时,selectedSecurity通过订阅selectedSecurity$异步获取,若updateQuestions在selectedSecurity赋值前执行,会导致问题列表过滤逻辑失效;同时原逻辑未严格保证updateQuestions仅在assessmentData加载完成后触发。

具体解决方案

1. 完善加载状态管理

在setAssessmentData发起请求时标记加载状态为true,成功和错误回调中都重置为false,确保UI能正确反映数据加载状态。

2. 同步selectedSecurity与assessmentData的加载时机

先订阅selectedSecurity$确保值能及时获取,在selectedSecurity更新时,若assessmentData已加载完成且存在有效securityControl,自动触发updateQuestions。

3. 清理订阅防止内存泄漏

添加订阅数组管理所有异步订阅,在组件销毁时统一取消订阅。

修改后的代码

import { Subscription } from 'rxjs';

// 组件类中新增订阅管理数组
subscriptions: Subscription[] = [];

ngOnInit() {
  this.isControlSecurityComplete = this.navigationService.getControlSecurityComplete();

  // 先订阅selectedSecurity$,确保值更新时同步刷新问题列表
  const securitySub = this.dataService.selectedSecurity$.subscribe((value) => {
    this.selectedSecurity = value;
    // 若评估数据已加载完成且存在有效安全控制,重新更新问题
    if (!this.isAssessmentDataLoading && this.assessmentData.securityControl) {
      this.updateQuestions(this.assessmentData.securityControl);
    }
  });
  this.subscriptions.push(securitySub);

  // 启动评估数据加载
  this.setAssessmentData(this.navigationService.getSavedID());

  if (this.isControlSecurityComplete) {
    this.questions.forEach(question => {
      question.selectedOption = null;
    });
  }
}

setAssessmentData(assessmentID: string) {
  this.isAssessmentDataLoading = true; // 开始加载时标记状态
  this.assessmentService.getAssessmentById(assessmentID).subscribe(
    (assessment) => {
      // 赋值评估数据
      this.assessmentData.nomeAssessment = assessment['nomeAssessment'];
      this.assessmentData.dataAssessment = assessment['dataAssessment'];
      this.assessmentData.nomeStruttura = assessment['nomeStruttura'];
      this.assessmentData.nomeCittaOSito = assessment['nomeCittaOSito'];
      this.assessmentData.statoProvinciaRegione = assessment['statoProvinciaRegione'];
      this.assessmentData.contatti.nome = assessment['contatti']?.nome;
      this.assessmentData.contatti.ruolo = assessment['contatti']?.ruolo;
      this.assessmentData.contatti.email = assessment['contatti']?.email;
      this.assessmentData.selectedCategory = assessment['selectedCategory'];
      this.assessmentData.securityLevel = assessment['securityLevel'];
      this.assessmentData.securityControl = assessment['securityControl'];
      this.assessmentData.domande = assessment['domande'];
      this.assessmentData.rispostaChatGPT = assessment['rispostaChatGPT'];

      // 处理安全控制状态与问题更新
      if (this.assessmentData.securityControl === '') {
        this.controlSelected = true;
      } else {
        this.controlSelected = false;
        // 仅当selectedSecurity已赋值时才调用updateQuestions,否则等订阅触发后自动执行
        if (this.selectedSecurity !== undefined) {
          this.updateQuestions(this.assessmentData.securityControl);
        }
      }

      this.isAssessmentDataLoading = false; // 加载完成后重置状态
    },
    (error) => {
      this.isAssessmentDataLoading = false;
      console.error('Errore nel recupero dell\'assessment', error);
    }
  );
}

updateQuestions(controlName: string) {
  this.dataService.getJsonDataNew(controlName).subscribe((data) => {
    if (data && data.fileDocument && Array.isArray(data.fileDocument.fileData)) {
      this.questions = data.fileDocument.fileData.filter((item: any) => item.Security <= this.selectedSecurity);
    } else {
      this.questions = [];
    }
  });
}

// 组件销毁时清理所有订阅
ngOnDestroy() {
  this.subscriptions.forEach(sub => sub.unsubscribe());
}

关键修改说明

  • 提前订阅selectedSecurity$,确保selectedSecurity的值能及时同步,且在值变化时自动刷新问题列表(当评估数据已加载完成时)。
  • 统一管理isAssessmentDataLoading状态,避免加载状态异常。
  • 添加订阅清理逻辑,防止内存泄漏。
  • 在调用updateQuestions前检查selectedSecurity是否已赋值,避免过滤逻辑因未定义值失效。

内容的提问来源于stack exchange,提问作者Mario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 05:44:52