You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不使用ngFor索引的情况下为排序后的div行设置交替颜色

解决Angular ngFor过滤后行交替颜色问题

问题核心:直接使用原始数组的index会因为过滤逻辑(按年份筛选)导致展示的行索引不连续,无法实现正确的交替颜色。

方案1:组件内预处理分组数据(推荐,性能更优)

在组件中提前将数据按年份分组并过滤,模板直接遍历处理后的分组数据,此时ngFor的index就是当前年份下展示行的连续序号。

1.1 组件逻辑修改

// 在组件类中添加属性和初始化逻辑
groupedActivities: { year: string; activities: any[] }[] = [];

ngOnInit(): void {
  // 基于已有activityYears和activityData生成分组数据
  this.groupedActivities = this.activityYears.map(year => ({
    year,
    activities: this.activityData.filter(activity => activity.activityYear === year)
  }));
}

1.2 模板修改

<div *ngFor="let group of groupedActivities">
  <div class="bold">{{group.year}}</div>
  <!-- 遍历当前年份下的过滤后数据,使用i作为连续索引 -->
  <div *ngFor="let activity of group.activities; let i = index">
    <div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="10px"
         [ngClass]="{'even-row': i % 2 === 0, 'odd-row': i % 2 !== 0}">
      <div fxLayout="row wrap" fxLayoutAlign="start start" fxLayoutGap="10px">
        <div class="width-80px" [ngStyle]="{'color':seasonColour(activity.activitySeason)}">{{activity.activitySeason}}</div>
        <div class="width-200px bold" [ngStyle]="{'color':roleColour(activity.character)}">{{activity.character}}</div>
        <ng-container *ngIf="!isEditing">
          <div [ngStyle]="{'color':covenantServiceColour(activity.covenantService)}">{{activity.activity}}</div>
        </ng-container>
        <ng-container *ngIf="isEditing && idEdit === activity.activityID">
          <div [ngStyle]="{'color':covenantServiceColour(activity.covenantService)}" class="width-500px">
            <mat-form-field appearance="outline" class="fill-container">
              <mat-label>Activity</mat-label>
              <input matInput type="text" [(ngModel)]="activityEdit" [ngModelOptions]="{standalone: true}">
            </mat-form-field>
          </div>
        </ng-container>
        <ng-container *ngIf="isEditing && idEdit === activity.activityID">
          <div>
            <mat-checkbox [checked]="activity.covenantService" #covServCheckbox
                          (change)="covServiceSelect($event, activity.activityID, activity.activityYear, activity.activitySeason, activity.activitySeasonID, activity.character, activity.activity, activity.characterRole)">
              Covenant Service
            </mat-checkbox>
          </div>
        </ng-container>
      </div>
    </div>
  </div>
</div>

1.3 添加CSS样式

.even-row {
  background-color: #f5f5f5;
}
.odd-row {
  background-color: #ffffff;
}

方案2:使用自定义过滤管道

如果不想修改组件逻辑,可以创建一个过滤管道,在模板中直接过滤数据,此时ngFor的index也是过滤后的连续序号。

2.1 创建过滤管道

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({ name: 'filterByYear' })
export class FilterByYearPipe implements PipeTransform {
  transform(activities: any[], targetYear: string): any[] {
    return activities.filter(activity => activity.activityYear === targetYear);
  }
}

记得在对应模块中声明这个管道。

2.2 模板修改

<div *ngFor="let year of activityYears">
  <div class="bold">{{year}}</div>
  <!-- 使用管道过滤后,i为当前年份下的连续索引 -->
  <div *ngFor="let activity of activityData | filterByYear: year; let i = index">
    <div fxLayout="row" fxLayoutAlign="space-between center" fxLayoutGap="10px"
         [ngClass]="{'even-row': i % 2 === 0, 'odd-row': i % 2 !== 0}">
      <!-- 内部内容与原代码一致 -->
      <div fxLayout="row wrap" fxLayoutAlign="start start" fxLayoutGap="10px">
        <div class="width-80px" [ngStyle]="{'color':seasonColour(activity.activitySeason)}">{{activity.activitySeason}}</div>
        <div class="width-200px bold" [ngStyle]="{'color':roleColour(activity.character)}">{{activity.character}}</div>
        <ng-container *ngIf="!isEditing">
          <div [ngStyle]="{'color':covenantServiceColour(activity.covenantService)}">{{activity.activity}}</div>
        </ng-container>
        <ng-container *ngIf="isEditing && idEdit === activity.activityID">
          <div [ngStyle]="{'color':covenantServiceColour(activity.covenantService)}" class="width-500px">
            <mat-form-field appearance="outline" class="fill-container">
              <mat-label>Activity</mat-label>
              <input matInput type="text" [(ngModel)]="activityEdit" [ngModelOptions]="{standalone: true}">
            </mat-form-field>
          </div>
        </ng-container>
        <ng-container *ngIf="isEditing && idEdit === activity.activityID">
          <div>
            <mat-checkbox [checked]="activity.covenantService" #covServCheckbox
                          (change)="covServiceSelect($event, activity.activityID, activity.activityYear, activity.activitySeason, activity.activitySeasonID, activity.character, activity.activity, activity.characterRole)">
              Covenant Service
            </mat-checkbox>
          </div>
        </ng-container>
      </div>
    </div>
  </div>
</div>

注意:管道会在每次变更检测时执行,若数据量较大,推荐使用方案1的预处理方式以避免性能损耗。

内容的提问来源于stack exchange,提问作者Dusk Childer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:53:15