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) } }
问题原因
- 异步时序问题:
ngOnInit中调用seeMeBranch()发起异步请求获取分支列表,但请求完成前,页面可能已尝试使用初始值为undefined的selectedOption加载图表数据,导致请求路径中分支ID无效。 - 未主动触发首次加载逻辑:当前仅在手动触发
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
相关产品推荐
相关产品推荐

