Angular通过路由在droplist与cards组件间传递数据失败如何解决
问题解决方案
核心问题原因
- HTTP请求属于异步操作,你在
onSelect方法中先调用getCartes触发请求,立刻执行路由跳转,此时请求还未返回响应,this.information还未被赋值,导致路由传递的info是空值。 - Cards组件未对
info做初始化,直接用*ngFor遍历空值会导致渲染失败,且getCurrentNavigation仅在组件构造阶段有效,页面刷新后数据会丢失。 - 部分接口请求路径存在双斜杠错误(比如
http://localhost:3000//xxx),可能导致请求失败。
具体修改代码
1. Droplist组件修改
调整逻辑,将路由跳转放到请求成功的回调中,确保传递的数据是接口返回的最新结果,同时修复路径双斜杠问题:
// 去掉onSelect里的直接跳转,跳转逻辑放到getCartes的请求回调里 onSelect(){ this.getCartes(); } // 改造getCartes,每个请求成功赋值后执行跳转 getCartes() { console.log(this.selectedTheme); console.log(this.selectedMot); // 声明跳转方法,复用逻辑 const navigateToCards = () => { this.router.navigate(['./cards'], {state:{info:this.information }}) } // 全量查询 if(this.selectedTheme == "Tous les thèmes" && this.selectedMot == "Tous les mots"){ this.httpClient.get("http://localhost:3000/all").subscribe(res => { this.information=res; navigateToCards(); // 请求完成后再跳转 }) this.lasttheme=this.selectedTheme; this.lastmot=this.selectedMot; } // 按主题查询 else if (this.selectedTheme != this.lasttheme && (this.selectedMot=="" || this.selectedMot=="Tous les mots")) { this.httpClient.get("http://localhost:3000/"+this.selectedTheme).subscribe(res => { this.information=res; console.log(this.information); navigateToCards(); }) this.lasttheme=this.selectedTheme; this.lastmot=this.selectedMot; } else if(this.selectedMot == "Tous les mots" && this.selectedTheme == this.lasttheme){ this.httpClient.get("http://localhost:3000/"+this.selectedTheme).subscribe(res => { this.information=res; navigateToCards(); }) this.lastmot=this.selectedMot; } // 按关键词查询 else if (this.selectedMot != this.lastmot && (this.selectedTheme == "" || this.selectedTheme == "Tous les thèmes")) { this.httpClient.get("http://localhost:3000/"+this.selectedMot).subscribe(res => { this.information=res; navigateToCards(); }) this.lasttheme=this.selectedTheme; this.lastmot=this.selectedMot; } else if (this.selectedTheme == "Tous les thèmes" && this.selectedMot == this.lastmot){ this.httpClient.get("http://localhost:3000/"+this.selectedMot).subscribe(res => { this.information=res; navigateToCards(); }) this.lasttheme=this.selectedTheme; } // 按主题+关键词查询 else if ((this.selectedTheme != this.lasttheme && this.selectedTheme != "Tous les thèmes" && this.selectedMot != "" ) || (this.selectedMot != this.lastmot && this.selectedMot!="Tous les mots" && this.selectedTheme !="" )){ this.httpClient.get("http://localhost:3000/"+this.selectedTheme+"/"+this.selectedMot).subscribe(res => { this.information=res; navigateToCards(); }) this.lasttheme=this.selectedTheme; this.lastmot=this.selectedMot; } else { console.log(5) } };
2. Cards组件修改
增加空值兜底和初始化,避免渲染报错,同时兼容页面刷新场景:
export class CardsComponent implements OnInit { // 初始化空数组,避免遍历报错 info: any[] = []; constructor(private httpClient: HttpClient, private router:Router) { // 优先从导航状态取,兜底从history.state取,支持页面刷新 this.info = this.router.getCurrentNavigation()?.extras.state?.info || history.state?.info || []; } ngOnInit(): void { } }
模板部分可选增加空状态判断,优化用户体验:
<ng-container *ngIf="info.length > 0; else noData"> <button id ="element.id_Scenario" *ngFor="let element of info" >{{element.Nom_Scenario}}</button> </ng-container> <ng-template #noData> <p>暂无匹配数据</p> </ng-template> <router-outlet></router-outlet>
内容的提问来源于stack exchange,提问作者Nikita Shimolin
相关产品推荐
相关产品推荐

