Angular 4跨组件展示搜索结果为空问题求助
问题分析与解决方案
你遇到的核心问题是异步操作的执行时机不对,导致在服务器数据还没返回时就尝试使用它。咱们一步步拆解问题,然后给出修复方案:
问题1:Service中异步操作未完成就返回数据
你的getSearchList方法里,HTTP请求是异步的(通过toPromise()处理),但你在then()回调之外直接返回了this.patientList1——这时候请求还没完成,patientList1还没被赋值,所以返回的是空值。
问题2:Layout组件未等待异步请求完成就跳转
在search方法里,你调用getSearchList后立刻执行router.navigate,这时候服务器的数据还没回来,跳转后的Search组件自然拿不到数据。
修复步骤
1. 修改Service方法,返回Promise让调用方等待
把getSearchList改成返回Promise,这样调用者可以等待请求完成后再处理后续逻辑:
// Service代码修改后 getSearchList(searchTerm: string): Promise<Patient[]> { const headerOptions = new Headers({ 'Content-Type': 'application/json', 'Authorization': 'Bearer ' + this.authenticationService.token }); const requestOptions = new RequestOptions({ method: RequestMethod.Get, headers: headerOptions }); // 直接返回HTTP请求的Promise,同时在then里赋值patientList1 return this.http.get(`/api/search/${searchTerm}`, requestOptions) .map((response: Response) => { console.log('data from server', response.json()); return response.json() as Patient[]; }) .toPromise() .then(x => { this.patientList1 = x; console.log('data from server', this.patientList1); return x; // 把数据返回给调用方 }); }
2. 修改Layout组件的search方法,等待Promise完成后再跳转
在调用getSearchList后,通过await等待请求完成,再执行页面跳转:
// Layout组件TypeScript代码修改后 async search(event: any) { // 等待搜索请求完成 await this.patientService.getSearchList(event.target.value); console.log('#####patients after search===', this.patientService.patientList1); // 数据加载完成后再跳转 this.router.navigate(['/search']); setTimeout(() => this.ref.markForCheck()); }
3. 优化Search组件的数据获取(可选但推荐)
直接在模板中引用patientService.patientList1虽然能工作,但更好的方式是让Search组件自己处理数据,避免依赖全局状态:
比如在Search组件中:
// searchcomponent.ts patientList: Patient[] = []; constructor(private patientService: PatientService, private route: ActivatedRoute) {} ngOnInit() { // 通过路由参数获取搜索关键词并发起请求 this.route.queryParams.subscribe(params => { const searchTerm = params['term']; if (searchTerm) { this.patientService.getSearchList(searchTerm).then(data => { this.patientList = data; }); } }); }
对应的模板修改为:
<table class="table table-sm table-hover"> <tr> <th>Firstname</th> <th>ID</th> <th>Lastname</th> <th>Phone</th> </tr> <tr *ngFor="let pat of patientList"> <td>{{ pat.ID }}</td> <td>{{ pat.firstname }}</td> <td>{{ pat.lastname }}</td> <td>{{ pat.phone }}</td> </tr> </table>
同时Layout组件的跳转改为传递查询参数:
async search(event: any) { const searchTerm = event.target.value; await this.patientService.getSearchList(searchTerm); this.router.navigate(['/search'], { queryParams: { term: searchTerm } }); }
总结
核心就是要尊重异步操作的执行顺序,确保在数据返回后再进行页面跳转或者数据渲染。通过让Service返回Promise,调用方等待异步完成,就能解决数据为空的问题。
内容的提问来源于stack exchange,提问作者prasannakumar chebrolu
相关产品推荐
相关产品推荐

