*ngFor - 如果找到,如何在模板循环中覆盖值

Posted

技术标签:

【中文标题】*ngFor - 如果找到,如何在模板循环中覆盖值【英文标题】:*ngFor - How to Override Value in a Template Loop if found 【发布时间】:2019-09-20 10:56:07 【问题描述】:

我有一个如下所示的对象数组:

newItems = [
   id: 8997, yellow: 'Y', red: 'N', reportId: 1 , //HewlettPackard 
   id: 8997, yellow: 'N', red: 'N', reportId: 2 , //HewlettPackard 
   id: 6300, yellow: 'N', red: 'Y', reportId: 2 , //EpsonCenter5000
   id: 0019, yellow: 'Y', red: 'N', reportId: 1   //another report
]

我正在使用 ngFor 遍历对象,它工作正常。基本上,如果在一个对象中,黄色或红色设置为“Y”,则显示相应的色环。

一个类别 ID (id) 可以显示大约 4 个报告 (reportID)。

<div *ngFor="let loop of newItems">
<table>
   <ng-template *ngIf="loop.yellow = 'Y' && loop.red == 'N' && loop.reportId == 1">
      <tr>
         <td class="yellow">Polaris South</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.red = 'Y' && loop.yellow == 'N' && loop.reportId == 1">
      <tr>
         <td class="red">Polaris South</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.reportId !== 1">
      <tr>
         <td class="green">Polaris South</td>
      </tr>
   </ng-template>
   ***********************
   <ng-template *ngIf="loop.yellow = 'Y' && loop.red == 'N' && loop.reportId == 2">
      <tr>
         <td class="yellow">Dandride</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.red = 'Y' && loop.yellow == 'N' && loop.reportId == 2">
      <tr>
         <td class="red">Dandride</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.reportId !== 2">
      <tr>
         <td class="green">Dandride</td>
      </tr>
   </ng-template>

  ********************
   <ng-template *ngIf="loop.yellow = 'Y' && loop.red == 'N' && loop.reportId == 3.1">
      <tr>
         <td class="yellow">Opmanual Internal</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.red = 'Y' && loop.yellow == 'N' && loop.reportId == 3.1">
      <tr>
         <td class="red">Opmanual Internal</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.reportId !== 3.1">
      <tr>
         <td class="green">Opmanual Internal</td>
      </tr>
   </ng-template>

   **************************
   <ng-template *ngIf="loop.yellow = 'Y' && loop.red == 'N' && loop.reportId == 3.2">
      <tr>
         <td class="yellow">Zetaphi Remarks</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.red = 'Y' && loop.yellow == 'N' && loop.reportId == 3.2">
      <tr>
         <td class="red">Zetaphi Remarks</td>
      </tr>
   </ng-template>
   <ng-template *ngIf="loop.reportId !== 3.2">
      <tr>
         <td class="green">Zetaphi Remarks</td>
      </tr>
   </ng-template>
</table>
</div>

问题是,对于每个类别(即 Hewlett Packard、Epson Center 5000)所在的框,如果为不同的 ReportId 找到黄色和红色值,因为 for 循环循环遍历对象的迭代,您会得到重复的结果如果有多个报告(单个 id 的报告 ID)。见截图。

我的目标是,如果黄色设置为“Y”,则在 id 匹配的任何迭代中显示它,红色相同但不重复,相反,如果找到“Y”,则覆盖绿色默认值。

【问题讨论】:

嗨,下面的解决方案对你有用吗? 【参考方案1】:

非常好的问题 - 在没有 TS 功能的情况下这样做会更具挑战性...您可以查看working demo here

我更改了数组的结构(函数 sortArraybyID),以便我们可以分隔产品线的部分('HewlettPackard'、'EpsonCenter5000'、'another report')。 接下来,因为我们必须为每个报告 ID 设置一行,所以我们也将其放入一个数组中,然后简单地打印出来 默认情况下,我们会针对所有报告打印一个绿色圆圈 - 因此所有行都变为绿色(默认情况下) 接下来,如果找到匹配项,我们只需覆盖圆圈 - 关键是要有更大的 z-index :)

更新了 app.component.ts

import  Component  from '@angular/core';

@Component(
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
)
export class AppComponent 
  name = 'Angular';
  newItems = [];
  newArray: any[] = [];
  mustHaveArray: any[] = [];

  constructor() 
    this.mustHaveArray = [
       reportId: 1, descr: 'Polaris South' , 
       reportId: 2, descr: 'Dandride' ,
       reportId: 3.1, descr: 'Opmanual Internal' , 
       reportId: 3.2, descr: 'Zetaphi Remarks' 
    ];
    this.newItems = [
       id: '8997', yellow: 'Y', red: 'N', reportId: 1 , //HewlettPackard 
       id: '8997', yellow: 'N', red: 'Y', reportId: 2 , //HewlettPackard 
       id: '8997', yellow: 'N', red: 'N', reportId: 3.1 , //HewlettPackard 
       id: '8997', yellow: 'Y', red: 'N', reportId: 3.2 , //HewlettPackard 

       id: '6300', yellow: 'N', red: 'Y', reportId: 1 , //EpsonCenter5000
       id: '6300', yellow: 'Y', red: 'N', reportId: 2 , //EpsonCenter5000

       id: '0019', yellow: 'Y', red: 'N', reportId: 1 , //another report
       id: '0019', yellow: 'N', red: 'Y', reportId: 2 , //another report
    ];
    this.sortArraybyID();
  

  sortArraybyID() 

    for (var i = 0; i < this.newItems.length; i++) 
      //console.log(i+" off" + this.newItems.length +" for:"+this.newItems[i].id);

      let checkForID: boolean = false;
      for (var j = 0; j < this.newArray.length; j++) 
        if (this.newArray[j].id === this.newItems[i].id)  checkForID = true; break; 
      
      if (checkForID == false) 
        this.newArray.push( id: this.newItems[i].id, details: [ yellow: this.newItems[i].yellow, red: this.newItems[i].red, reportId: this.newItems[i].reportId ] );
       else 
        this.newArray[j].details.push( yellow: this.newItems[i].yellow, red: this.newItems[i].red, reportId: this.newItems[i].reportId );
      
    
    //console.log(this.newArray);
  

更新了 app.component.html

<div class='tableDiv2' *ngFor="let outer of newArray, let i = index">
    <table>
        <thead>
            <th>
                <tr> Category [i] <br/> ID:outer.id </tr>
            </th>
        </thead>
        <ng-container>

            <tbody>
                <tr *ngFor="let category of mustHaveArray">
                    <td>
                        <ng-container *ngFor="let loop of outer.details; let idx2 = index">
                            <div class='defaultClass'>
                            </div>
                            <div *ngIf="category.reportId == loop.reportId" [ngClass]="(loop.yellow == 'Y' && loop.red == 'N') ? 'yellow' : (loop.yellow == 'N' && loop.red == 'Y') ? 'red' : 'green'  ">
                            </div>
                        </ng-container>
                        <span class='descrClass'>
           category.descr
           </span>

          </td>
                </tr>
            </tbody>

        </ng-container>
    </table>
</div>

更新了 app.component.css

.yellow , .red , .green
 border-radius: 50%; height:20px; width: 20px; position: absolute; text-align: center !important; 
z-index:2;


.defaultClass  background:lightgreen; border-radius: 50%; height:20px; width: 20px; position: absolute; text-align: center !important; z-index:1; 


.yellow  background:yellow;   
.red  background:lightpink;  
.green  background:lightgreen; 

.tableDiv2float:left; width:24%;
.tableDivfloat:left; width:12%;
.oldData width:100%;  height:10px; float:left;

.oldData .tableDiv background:lightgrey;
.descrClass margin-left:25px; text-align: left !important;

【讨论】:

这项工作...进行了一些调整以匹配我的数据,但它显示完美。 When someone goes on Stack Exchange, the question "answer" should actually contain an answer. Not just a bunch of directions/links towards the answer.. @ErikPhilips,我描述了我为解决问题所做的所有更改;我怎么能给出更好的答案...通过包含所有代码? 是的,包括所有代码。这就是网站的重点。如果您的链接失效,那么您的回答对所有阅读它的人来说都是无用的。 @ErikPhilips 更新了答案...当我看到赞成票时,我会知道你批准了 :)

以上是关于*ngFor - 如果找到,如何在模板循环中覆盖值的主要内容,如果未能解决你的问题,请参考以下文章

如何将 ngFor 循环的索引值传递给组件? [复制]

将 ngFor 变量传递给 ngIf 模板

如何在Angular中使用ngFor循环对象属性

如何根据对象属性字符串过滤“ngFor”循环内的项目

ngFor 块内模板中的异步管道触发 http GET 调用循环

如何使用包含键作为字符串和值作为映射迭代的ngFor循环映射进行迭代