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

Angular页面首次加载预设下拉选中项并加载数据失败问题

问题描述

使用Angular开发测试项目,需求为选择分支后加载对应分支信息的图表。期望页面首次加载时,mat-select下拉框预设选中API返回的首个分支并自动加载数据,但目前首次加载时触发400错误(请求路径中分支ID为undefined),仅手动选择分支时数据能正常显示。

错误信息:

Error: {"timestamp":"2023-05- 11T21:21:09.099+00:00","status":400,"error":"Bad Request","path":"/api/events/quantity/branch/undefined"}

相关代码

HTML模板

<mat-form-field style="margin-top: 25px;align-items: right" appearance="fill">
  <mat-label>Selecione uma Filial</mat-label>
  <mat-select [value]='selectedOption' (selectionChange)="onSelectionChange($event)">
    <mat-option *ngFor="let select of selectedAll" [value]="select.id">{{select.name}}</mat-option>
  </mat-select>
</mat-form-field>

Component.ts代码

import { Component, OnInit, ViewChild, Output, EventEmitter } from '@angular/core';
import { Chart, registerables } from 'chart.js';
Chart.register(...registerables);
import { ChartOptions } from 'chart.js';
import { AccountService } from '../account/shared/account.service';
import { Observable } from 'rxjs';
import { MatSelect } from '@angular/material/select';

@Component({
  selector: 'app-charts',
  templateUrl: './charts.component.html',
  styleUrls: ['./charts.component.scss'],
})
export class ChartsComponent implements OnInit {

  @ViewChild('changeEl', { static: false }) changeEl?: MatSelect;
  public selectItemBranch?: Observable<any>;
  itemBranch: any = [];
  itemsEvents: any = [];
  itemsDrivers: any = [];
  itemsAssets: any = [];
  selectedOption: any;

  @Output() newItemBranchEvent = new EventEmitter<any>();

  selectedAll: any = [];
  public selectedBranch: any;
  selected: any = [];


  public barChartOptions: ChartOptions = {
    responsive: true,
    indexAxis: 'y',

  };

  onSelectionChange(itemBranch: any) {
    this.itemsAssets = []
    this.itemsDrivers = []
    this.itemsEvents = []
    this.selectItemBranch = itemBranch.value;
    console.log(this.selectItemBranch);
  }

  seeMeBranch() {
    this.selected = this.accountService.meBranch().subscribe(
      resp => {
        this.selectedAll = resp;
        this.selectedBranch = this.selectedAll.id
        this.selectedOption = this.selectedAll[0].id
        console.log(this.selectedOption)
      });

  }

  addItemEvents(event: any) {
    this.itemsEvents = event;
  }

  filterBranch(name: string) {
    let arr = this.selectedAll.filter(
      (branch: any) => branch.name.toLowerCase().indexOf(name.toLowerCase()) === 0
    );

    return arr.length ? arr : [{ name: 'No Item found' }];
  }

  addItemDrivers(event: any) {
    this.itemsDrivers = event;
  }

  addItemAssets(event: any) {
    this.itemsAssets = event;
  }

  addItemBranch(event: any) {
    this.itemBranch = event;
  }

  constructor(private accountService: AccountService) {
  }

  ngOnInit() {
    console.log(this.selectedOption)
    this.seeMeBranch();
    console.log(this.selectedBranch)
  }
}

问题原因

  1. 异步时序问题:ngOnInit中调用seeMeBranch()发起异步请求获取分支列表,但请求完成前,页面可能已尝试使用初始值为undefined的selectedOption加载图表数据,导致请求路径中分支ID无效。
  2. 未主动触发首次加载逻辑:当前仅在手动触发selectionChange事件时才处理分支选择后的逻辑,首次设置selectedOption后没有主动触发数据加载流程。

解决方案

方案1:分支数据加载完成后主动触发数据加载

修改seeMeBranch()方法,在获取分支数据并设置selectedOption后,直接调用数据加载逻辑,同时封装通用加载方法优化代码:

seeMeBranch() {
  this.accountService.meBranch().subscribe(
    resp => {
      this.selectedAll = resp;
      if (this.selectedAll.length > 0) {
        this.selectedOption = this.selectedAll[0].id;
        // 主动触发首个分支的数据加载
        this.loadBranchData(this.selectedOption);
        console.log(this.selectedOption);
      }
    },
    error => {
      console.error('获取分支列表失败', error);
    });
}

// 封装分支数据加载逻辑,替代原onSelectionChange中的重复代码
loadBranchData(branchId: any) {
  this.itemsAssets = [];
  this.itemsDrivers = [];
  this.itemsEvents = [];
  this.selectItemBranch = branchId;
  // 此处添加对应API调用,加载events、drivers、assets数据
  // 示例:
  // this.accountService.getEventsByBranch(branchId).subscribe(data => this.itemsEvents = data);
  // this.accountService.getDriversByBranch(branchId).subscribe(data => this.itemsDrivers = data);
  // this.accountService.getAssetsByBranch(branchId).subscribe(data => this.itemsAssets = data);
}

// 修改onSelectionChange,调用封装好的加载方法
onSelectionChange(itemBranch: any) {
  this.loadBranchData(itemBranch.value);
}

方案2:确保下拉框在数据就绪后渲染

在HTML模板中添加*ngIf,确保selectedAll有数据后再渲染mat-select,避免初始时selectedOption为undefined的情况:

<mat-form-field style="margin-top: 25px;align-items: right" appearance="fill">
  <mat-label>Selecione uma Filial</mat-label>
  <mat-select *ngIf="selectedAll.length > 0" [value]="selectedOption" (selectionChange)="onSelectionChange($event)">
    <mat-option *ngFor="let select of selectedAll" [value]="select.id">{{select.name}}</mat-option>
  </mat-select>
</mat-form-field>

额外注意事项

  • 确保accountService.meBranch()返回数组类型,且this.selectedAll[0]存在,避免数组为空导致的报错。
  • 可添加加载状态提示,在分支数据未加载完成时显示加载动画,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 00:00:05