Angular如何将服务中的异步请求变量绑定到组件模板
修复方案
你的代码存在3个核心问题:
- 模板中对普通变量使用了仅支持Observable/Promise的
async管道 - 服务中
contactsData没有初始化默认值,首次渲染时访问属性会报错 *ngFor循环的数据源层级和模板取值层级不匹配
方案1:直接绑定服务变量(无需异步管道)
1. 修改service.ts
首先给contactsData添加初始值,原请求逻辑保留即可:
// 先声明变量并赋初始值,避免首次渲染空值报错 public contactsData: any = { data: [] }; getData() { this.appService.postHTTPRequest(this.contactsURL).subscribe(response => { this.contactsData = response; console.log(this.contactsData); }, error => { console.log("An error has occurred"); }); }
2. 修改component.html
移除async管道,调整循环层级,建议把循环移到tr标签避免生成多个tbody:
<tbody style="margin:auto;"> <tr *ngFor="let cData of contactsService.contactsData.data"> <td>{{cData.name}}</td> </tr> </tbody>
如果要保留循环在tbody上,修改为:
<tbody *ngFor="let cData of contactsService.contactsData.data" style="margin:auto;"> <tr> <td>{{cData.name}}</td> </tr> </tbody>
方案2:响应式流写法(符合Angular最佳实践)
1. 修改service.ts
用BehaviorSubject存储响应式数据,对外暴露可观察对象:
import { BehaviorSubject } from 'rxjs'; // 私有Subject用来更新数据 private contactsDataSub = new BehaviorSubject<any>({ data: [] }); // 对外暴露的可观察对象,供模板订阅 public contactsData$ = this.contactsDataSub.asObservable(); getData() { this.appService.postHTTPRequest(this.contactsURL).subscribe(response => { // 把新数据推送到流中 this.contactsDataSub.next(response); console.log(response); }, error => { console.log("An error has occurred"); }); }
2. 修改component.html
使用async管道订阅可观察对象,自动管理订阅生命周期:
<tbody style="margin:auto;"> <tr *ngFor="let cData of (contactsService.contactsData$ | async)?.data"> <td>{{cData.name}}</td> </tr> </tbody>
两种方案都可以正常运行,组件中的代码不需要做任何修改。如果接口返回结构和假设的不一致,调整取值的层级即可。
内容的提问来源于stack exchange,提问作者user15334378
相关产品推荐
相关产品推荐

