Angular 15从对象数组取值计算并前端映射的问题求助
Angular 15 计算对象密度并前端展示问题解决思路
我使用Angular 15,需要从对象数组中提取属性计算密度,然后在前端页面映射展示。尝试了三种仅subscribe部分不同的方法,都没达到预期效果。
组件基础代码
export class LeftPanelComponent implements OnInit { objects: Objects[] = []; density: Array<Number> = []; }
方法1及问题
getObjects(): void { this.restService.getObjects() .subscribe((objects: any) => { this.objects = objects; const promise$ = from(objects); promise$ .pipe(map((obj:any) => ((obj.mass)/(obj.height * obj.length * obj.width)))) .subscribe((value) => console.log(`Emitted Values: `, value)); }); }
结果:
控制台打印所有正确密度值:
Emitted Values: 253.96825396825395 Emitted Values: 4.444444444444445 Emitted Values: 666.6666666666665 Emitted Values: 200 Emitted Values: 166.66666666666669 Emitted Values: 1666.6666666666667
但前端无法展示密度值。
问题:仅将计算结果打印到控制台,未存入density数组供前端绑定使用。
方法2及问题
getObjects(): void { this.restService.getObjects() .subscribe((objects: any) => { this.objects = objects; const promise$ = from(objects); promise$ .pipe(map((obj:any) => ((obj.mass)/(obj.height * obj.length * obj.width)))) .subscribe((value:any) => { this.density = value }); }); }
结果:
前端表格所有行均显示最后一个密度值:
Name Density Van 1666.6666666666667 Pine tree 1666.6666666666667 Snake 1666.6666666666667 Giraffe 1666.6666666666667 Sheet of paper 1666.6666666666667 Television 1666.6666666666667
问题:每次回调将单个密度值直接赋值给density数组,覆盖之前内容,最终数组仅保留最后一个值。
方法3及问题
getObjects(): void { this.restService.getObjects() .subscribe((objects: any) => { this.objects = objects; const promise$ = from(objects); promise$ .pipe(map((obj:any) => ((obj.mass)/(obj.height * obj.length * obj.width)))) .subscribe(((value:any) => { for(let i=0; i<value.length; i++) { this.density[i] = value; } })); }); }
结果:前端页面无任何显示效果。
问题:value是单个密度数值,并非数组,value.length不存在,循环无法执行,density数组始终为空。
解决思路
方案1:直接遍历数组计算(无需RxJS from操作)
拿到完整objects数组后直接遍历计算,逻辑简单直观:
getObjects(): void { this.restService.getObjects() .subscribe((objects: any) => { this.objects = objects; // 清空原有数据,避免重复累加 this.density = []; objects.forEach(obj => { const calcDensity = obj.mass / (obj.height * obj.length * obj.width); this.density.push(calcDensity); }); }); }
前端通过索引绑定两个数组:
<table> <tr> <th>Name</th> <th>Density</th> </tr> <tr *ngFor="let obj of objects; let i = index"> <td>{{ obj.name }}</td> <td>{{ density[i] }}</td> </tr> </table>
方案2:使用RxJS toArray()收集结果
若坚持用RxJS,可通过toArray()将单个发射的值收集为完整数组后一次性赋值:
getObjects(): void { this.restService.getObjects() .subscribe((objects: any) => { this.objects = objects; from(objects) .pipe( map((obj:any) => obj.mass / (obj.height * obj.length * obj.width)), toArray() // 将所有发射值收集为一个数组 ) .subscribe((densityArray) => { this.density = densityArray; }); }); }
此方式减少多次修改数组触发的变更检测,性能更优。
方案3:增强对象结构(最推荐)
直接给每个对象添加density属性,无需维护两个数组的索引对应关系,代码更简洁可靠:
getObjects(): void { this.restService.getObjects() .subscribe((objects: any) => { this.objects = objects.map(obj => ({ ...obj, density: obj.mass / (obj.height * obj.length * obj.width) })); }); }
前端直接绑定对象属性:
<table> <tr> <th>Name</th> <th>Density</th> </tr> <tr *ngFor="let obj of objects"> <td>{{ obj.name }}</td> <td>{{ obj.density }}</td> </tr> </table>
内容的提问来源于stack exchange,提问作者YL Chan
相关产品推荐
相关产品推荐

