Angular 5 NgFor-遍历元素并检测已渲染的元素

时间:2018-08-05 15:08:17

标签: javascript angular html5 typescript multidimensional-array

我创建了一个交通灯,根据从数据库传递的值显示了(红色,黄色,绿色)圆圈。

当前,我正在使用颜色显示报告的状态。 *如果数组中只有1个对象,NgFor循环可以很好地将颜色放置在它们所属的位置。如果数据中没有reportId(report),则会出现一个“绿色”圆圈,即应该出现。一次只能显示3种颜色,不能重复显示。

问题是,如果values数组中存在第二个对象,则循环将忽略先前的值,并显示一个绿色圆圈,因为该reportId的值已存在,因此应忽略该位置。如前所述,如果“值”数组中只有1个对象,则它可以完美工作,并且在不存在的reportID的正确位置应用了绿色圆圈,但是当对象/报告列表超过一个时,它给我第二行信号灯,忽略了第一次迭代中的设置值。实际上,它将以前的reportID视为不存在,并放置一个绿色圆圈。

关于如何解决此问题的任何想法?我研究了ASYNC管道,但不确定100%如何在这种情况下应用它。

enter image description here

数据如下:

{ key: 'Profit Loss', 
  value: [{ yellow: 'Y', red: 'N', reportId: 2 }]
},
{ key: 'Actuals', 
  value: [{ yellow: 'N', red: 'Y', reportId: 2 },
          { yellow: 'Y', red: 'N', reportId: 1 }]
}

循环的结构如此……

            <div *ngFor="let siteMap of reportRow; let i = index;" >
               {{ siteMap.key }}
            <div *ngFor="let pMap of siteMap.value; let xi = index;" >
                <!---Report 1---->
                <!--------------->
                <tr *ngIf="pMap.yellow === 'Y' && pMap.reportId === 1">
                  <td><span class="yellowcolor"></span> <b>Report 1 Yellow</b></td>
                </tr>
                <tr *ngIf="pMap.red === 'Y' && pMap.reportId === 1">
                  <td><span class="redcolor"></span> <b>Report 1 Red</b></td>
                </tr>
                <tr *ngIf="pMap.reportId !== 1">
                  <td><span  class="greencolor"></span><b>Report 1 Green</b></td>
                </tr>
                <!---Report 2---->
                <!--------------->
                <tr *ngIf="pMap.yellow === 'Y' && pMap.reportId === 2">
                  <td><span class="yellowcolor"></span> <b>Report 2 Yellow</b></td>
                </tr>
                <tr *ngIf="pMap.red === 'Y' && pMap.reportId === 2">
                  <td><span class="redcolor"></span> <b>Report 2 Red</b></td>
                </tr>
                <tr *ngIf="pMap.reportId !== 2">
                  <td><span  class="greencolor"></span> <b>Report 2 Green</b></td>
                </tr>
                <!---Report 3---->
                <!--------------->
                <tr *ngIf="pMap.yellow === 'Y' && pMap.reportId === 3">
                  <td><span class="yellowcolor"></span> <b>Report 3 Yellow</b></td>
                </tr>
                <tr *ngIf="pMap.red === 'Y' && pMap.reportId === 3">
                  <td><span class="redcolor"></span> <b>Report 3 Red</b></td>
                </tr>
                <tr *ngIf="pMap.reportId !== 3">
                  <td><span  class="greencolor"></span> <b>Report 3 Green</b></td>
                </tr>
            </div>

2 个答案:

答案 0 :(得分:1)

@MizAkita,由于该解决方案有效,因此将评论发布为答案。

让我们说您能够创建一个已经绘制了报告ID的数组,然后在循环*ngIf之后可以有另一个siteMap

<div *ngFor="let pMap of siteMap.value; let xi = index;"> 
   <div *ngIf="!newArray.includes(pMap.reportId)"> ... </div> 
</div>

答案 1 :(得分:-2)

您对此有多种解决方案,但是我要做的是将复杂的部分移到javascript:

在渲染之前对数组进行排序和填充:

ngOnInit() {

    let rawData = this.myService.get();

    for (let siteMap of rawData) {
        siteMap.value.sort(this.compare);
    }
    this.fillEmptyData(rawData);
    this.reportRow = rawData;
}

private compare(a,b) {
  if (a.reportId < b.reportId)
    return -1;
  if (a.reportId > b.reportId)
    return 1;
  return 0;
}

private fillEmptyData(dataToFill) {
    for (let column of dataToFill) {
        if (!column.value) {
            column.value = [];
        }
        for (let i = 0; i < 3; i++) {
            if (!column.value[i] || column.value[i].reportId !== (i + 1)) {
                // column.value[i] does not contain the expected reportId
                let emptyItem = {
                    reportId: i + 1,
                    reportName: 'Report ' + (i + 1), // or whatever
                    empty: true
                };
                // insert the empty item at the place it should be
                column.value.splice(i, 0, emptyItem);
            } else {
                column.value[i].reportName = 'Report ' + (i + 1);
            }
        }
    }
}

然后您将清除html部分:

<div *ngFor="let siteMap of reportRow; let i = index;" >
   {{ siteMap.key }}
    <div *ngFor="let pMap of siteMap.value; let xi = index;" >
        <tr *ngIf="pMap.yellow === 'Y'">
          <td><span class="yellowcolor"></span> <b>{{pMap.reportName}} Yellow</b></td>
        </tr>
        <tr *ngIf="pMap.red === 'Y'">
          <td><span class="redcolor"></span> <b>{{pMap.reportName}} Red</b></td>
        </tr>
        <tr *ngIf="pMap.empty === true">
          <td><span  class="greencolor"></span><b>{{pMap.reportName}} Green</b></td>
        </tr>
    </div>
</div>

结果如下: Result