Angular如何在HTML指定div中加载接口返回的动态数据
问题原因
- 核心为异步代码执行顺序错误:
this.calcualte.calculatePremium()发起的是异步HTTP请求,subscribe包裹的成功/失败回调函数需要等服务端返回结果后才会执行。你将DOM赋值、this.amount取值的代码写在了subscribe外部,JS主线程会优先执行同步代码,此时接口请求还未返回,this.amount还未被赋值,因此读取到的值为undefined。 - 额外问题:直接使用原生
documentAPI操作DOM不符合Angular框架的设计规范,也可能引发视图更新不同步的额外问题。
修复方案
方案1:快速修正原有写法
仅需将所有依赖接口返回值的操作,移动到subscribe的成功回调内部即可,修改后代码如下:
calculatePremium(){ console.log("calculating"); let frmData: any = this.form.value; this.dobVal = frmData.contact.dob; let onlyYear = String(this.dobVal).split(' ')[3]; // AGE let age = (Number(new Date().getFullYear()) - Number(onlyYear)); // NAME let name = frmData.contact.firstName; // GENDER let gender = frmData.contact.gender; // smoking let smoker = frmData.basicInfo.isSmoker; // no of dependents let dependentsCount = Number(frmData.basicInfo.adults) + Number(frmData.basicInfo.children); let finalObj = { 'name': name, 'age': age, 'gender': gender, 'smoking': smoker, 'dependent': dependentsCount } this.calcualte.calculatePremium(finalObj).subscribe( (data: any) => { // 接口返回成功后再执行赋值和DOM操作 console.log(data); Swal.fire('Plan Amount', 'is ' + data.name + data.amount, 'success'); this.amount = data.amount; console.log(this.amount); const x = document.getElementById('calculatedData'); x.innerHTML = `<div class="appendme">${this.amount}</div>`; const len = x.getElementsByTagName('div').length; console.log(len); }, (error) => { console.log(error); }); }
方案2:推荐的Angular原生数据绑定实现(无需操作DOM)
Angular自带数据响应式更新能力,无需手动操作DOM,修改成本更低、逻辑更简洁:
- 首先修改
app.component.html代码,使用插值表达式绑定amount变量:
<button mat-raised-button color="primary" mat-button class="nextButton" (click)="calculatePremium()"> Calculate </button> <div id="calculatedData"> <!-- 当amount存在时自动渲染对应内容 --> <div *ngIf="amount" class="appendme">{{amount}}</div> </div>
- 调整
app.component.ts代码,仅需在接口回调中给this.amount赋值即可,无需任何DOM操作:
calculatePremium(){ console.log("calculating"); let frmData: any = this.form.value; this.dobVal = frmData.contact.dob; let onlyYear = String(this.dobVal).split(' ')[3]; // AGE let age = (Number(new Date().getFullYear()) - Number(onlyYear)); // NAME let name = frmData.contact.firstName; // GENDER let gender = frmData.contact.gender; // smoking let smoker = frmData.basicInfo.isSmoker; // no of dependents let dependentsCount = Number(frmData.basicInfo.adults) + Number(frmData.basicInfo.children); let finalObj = { 'name': name, 'age': age, 'gender': gender, 'smoking': smoker, 'dependent': dependentsCount } this.calcualte.calculatePremium(finalObj).subscribe( (data: any) => { console.log(data); Swal.fire('Plan Amount', 'is ' + data.name + data.amount, 'success'); // 仅需赋值,Angular会自动更新视图 this.amount = data.amount; }, (error) => { console.log(error); }); }
内容的提问来源于stack exchange,提问作者Anonymous
相关产品推荐
相关产品推荐

