Angular中使用*ngFor遍历渲染动态二维数组的实现方法
问题根因
你现在输出三次重复全量数组的问题非常明确:*ngFor="let calculation of arr_name" 本身确实会遍历arr_name下的每一个子数组,但你插值的时候写的是{{arr_name}},直接绑定了整个外层数组,根本没用到遍历出来的单个子数组变量calculation,所以循环3次就会把整个数组完整打印3次。
另外你的TS代码还有个隐藏bug:你在循环里反复修改this.calc_的属性再push,this.calc_是引用类型,所有push进去的数组都会指向同一个对象引用,最后所有子数组的值都会被最后一次循环的计算结果覆盖,这个必须一起修,不然就算模板写对了值也是错的。
通用实现方案
不需要硬编码arr_name[0][0]这类固定索引,两层遍历就能适配任意动态长度的数组,同时修复TS侧的引用污染问题。
第一步:修复TS侧计算逻辑
把循环里复用全局calc_对象的写法改掉,每次循环直接生成新数组push,从根源避免引用类型的值覆盖问题:
calculate( ) { this.isShowDiv = !this.isShowDiv; this.sortArray() for(let i = 0; i < Positions.length - 1; i++) { // 原有计算逻辑保持不变 const dy_ = 111.3 * (Positions[i].lat - Positions[i + 1].lat) const lat_ = (Positions[i].lat + Positions[i + 1].lat) / 2 * 0.01745 const dx_ = 111.3 * Math.cos(lat_) * (Positions[i].lng - Positions[i + 1].lng) let distance_ = Math.sqrt(dx_ * dx_ + dy_ * dy_) distance_ = distance_ * 1000 const distanceRounded: number = +distance_.toFixed(1); const startTime = Positions[i].time.toString() const endTime = Positions[i+1].time.toString() const starTimeCalc = new Date(startTime) const endTimeCalc = new Date(endTime) let sBetweenPos = endTimeCalc.valueOf() - starTimeCalc.valueOf(); sBetweenPos = sBetweenPos * 0.001 const duration = distanceRounded / sBetweenPos const durationRounded: number = +duration.toFixed(1) // 直接push新数组,不要复用全局calc_引用 this.arr_name.push([distanceRounded, durationRounded, sBetweenPos]) } }
*如果你一定要用calc_存储中间值,记得每次循环开头加一句this.calc_ = new Calc()重新实例化,切断引用关联。
第二步:修改HTML模板遍历逻辑
用两层*ngFor分别遍历外层父数组、内层子数组,通过索引自动匹配你要的size/size2/size3标签,不管后续数组长度怎么变都能自动渲染:
<div [hidden]="isShowDiv" > <!-- 第一层:遍历每一组计算结果子数组 --> <div class="list-group" *ngFor="let calculation of arr_name"> <a class="list-group-item list-group-item-action" aria-current="true"> <div class="d-flex w-100 justify-content-between"> <!-- 第二层:遍历当前子数组的每个值,通过索引生成对应标签 --> <ng-container *ngFor="let val of calculation; let valIndex = index"> <h5 class="mb-1">size{{valIndex === 0 ? '' : valIndex + 1}}: {{val}}</h5> </ng-container> </div> </a> </div> </div>
如果要实现每个size项单独占一行的效果,给h5标签加块级样式或者在末尾加<br>标签即可,和你给出的目标展示格式完全一致。
内容的提问来源于stack exchange,提问作者du7ri
相关产品推荐
相关产品推荐

