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

Angular12中Mat-Icon点击全部变更问题:寻求单个图标修改方案

问题原因

你遇到的问题是因为所有星星组共享了同一个全局的rating变量——当你点击任意一个星星时,这个全局变量会被更新,所有依赖它的星星图标都会同步变化。同时HTML中的*ngIf="this.etoile=='star_'+i"逻辑错误,会导致图标无法正常显示。

解决方案

核心思路是为每个问题的每组星星分配独立的评分存储,让不同组的状态互不干扰。具体步骤如下:

1. 替换全局评分变量为分组存储

在组件类中删除全局的rating: number = 0;,改为两个对象分别存储两组星星的评分(对应你HTML中的两组按钮):

// 存储第一组星星的评分,键为问题索引(或问题ID)
firstQuestionRatings: { [key: number]: number } = {};
// 存储第二组星星的评分
secondQuestionRatings: { [key: number]: number } = {};

2. 修改点击事件方法

将原来的onClick拆分为两个方法,分别处理两组星星的点击,更新对应组的评分:

// 处理第一组星星的点击
onClickFirst(rating: number, questIndex: number) {
  this.firstQuestionRatings[questIndex] = rating;
  this.snackBar.open(`第一组评分:${rating} / ${this.starCount}`, '', {
    duration: this.snackBarDuration
  });
  return false;
}

// 处理第二组星星的点击
onClickSecond(rating: number, questIndex: number) {
  this.secondQuestionRatings[questIndex] = rating;
  this.snackBar.open(`第二组评分:${rating} / ${this.starCount}`, '', {
    duration: this.snackBarDuration
  });
  return false;
}

3. 修改图标显示逻辑

更新图标显示方法,让每个组根据对应存储的评分返回图标类型:

// 返回第一组星星的图标
showFirstIcon(i: number, questIndex: number) {
  const currentRating = this.firstQuestionRatings[questIndex] || 0;
  return currentRating >= i + 1 ? 'star' : 'star_border';
}

// 返回第二组星星的图标
showSecondIcon(i: number, questIndex: number) {
  const currentRating = this.secondQuestionRatings[questIndex] || 0;
  return currentRating >= i + 1 ? 'star' : 'star_border';
}

4. 更新HTML模板

移除无效的*ngIf条件,为每组星星绑定对应的点击方法和图标显示方法,并传递问题索引作为标识:

<li *ngFor="let quest of Questions; let questIndex = index">
  <!-- 第一组星星 -->
  <button 
    mat-icon-button 
    [color]="color" 
    *ngFor="let ratingId of ratingArr; index as i" 
    [id]="'star_first_' + questIndex + '_' + i" 
    (click)="onClickFirst(i+1, questIndex)" 
    matTooltip="{{ratingId+1}}" 
    matTooltipPosition="above"
  > 
    <mat-icon>
      {{ showFirstIcon(i, questIndex) }}
    </mat-icon>
  </button>
  <br><br>
  <!-- 第二组星星 -->
  <button 
    mat-icon-button 
    [color]="color" 
    *ngFor="let ratingId of ratingArr; index as i" 
    [id]="'star_second_' + questIndex + '_' + i" 
    (click)="onClickSecond(i+1, questIndex)" 
    matTooltip="{{ratingId+1}}" 
    matTooltipPosition="above"
  > 
    <mat-icon>
      {{ showSecondIcon(i, questIndex) }}
    </mat-icon>
  </button> 
</li>
修改后的完整代码

TypeScript代码

import { Component, OnInit, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core';
import { LoginService } from 'src/app/services/login.service';
import { NgxSpinnerService } from 'ngx-spinner';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-historique',
  templateUrl: './historique.component.html',
  styleUrls: ['./historique.component.css'],
  encapsulation: ViewEncapsulation.Emulated
})
export class HistoriqueComponent implements OnInit 
{
  @Input('color') public color: string = 'accent';
  @Output() public ratingUpdated = new EventEmitter();

  public snackBarDuration: number = 2000;
  public ratingArr : number[] = [];
  Questions: any = [];
  listDeReponses: any[] = [];
  starCount: number = 5;
  etoile: string='star_border';
  selectedRow :any;
  // 存储两组星星的独立评分
  firstQuestionRatings: { [key: number]: number } = {};
  secondQuestionRatings: { [key: number]: number } = {};

  myForm = new FormGroup({
    bouton: new FormControl('', [Validators.required]),
  });

  constructor(
    private _loginService: LoginService,
    public spinner: NgxSpinnerService,
    public dialog: MatDialog,
    public snackBar: MatSnackBar
  ) { }

  ngOnInit(): void 
  {
    for (let index = 1; index <= this.starCount; index++) 
    {
      this.ratingArr.push(index);
    }

    var mat = localStorage.getItem('matricule');
    var matricule1 = mat!.replace('"', '');
    var matricule = matricule1.replace('"', '');

    var for1 = localStorage.getItem('formation');
    var form = for1!.replace('"', '');
    var formation = form.replace('"', '');

     this._loginService.GetQuestionsByFormation(matricule,Number(formation)).subscribe(
      data => 
      {
        this.Questions = data;
      });
  }

  onClickFirst(rating: number, questIndex: number) {
    this.firstQuestionRatings[questIndex] = rating;
    this.snackBar.open(`第一组评分:${rating} / ${this.starCount}`, '', {
      duration: this.snackBarDuration
    });
    return false;
  }

  onClickSecond(rating: number, questIndex: number) {
    this.secondQuestionRatings[questIndex] = rating;
    this.snackBar.open(`第二组评分:${rating} / ${this.starCount}`, '', {
      duration: this.snackBarDuration
    });
    return false;
  }

  showFirstIcon(i: number, questIndex: number) {
    const currentRating = this.firstQuestionRatings[questIndex] || 0;
    return currentRating >= i + 1 ? 'star' : 'star_border';
  }

  showSecondIcon(i: number, questIndex: number) {
    const currentRating = this.secondQuestionRatings[questIndex] || 0;
    return currentRating >= i + 1 ? 'star' : 'star_border';
  }
}

export enum StarRatingColor 
{
  primary = "primary",
  accent = "accent",
  warn = "warn"
}

HTML代码

<li *ngFor="let quest of Questions; let questIndex = index">
  <!-- 第一组星星 -->
  <button 
    mat-icon-button 
    [color]="color" 
    *ngFor="let ratingId of ratingArr; index as i" 
    [id]="'star_first_' + questIndex + '_' + i" 
    (click)="onClickFirst(i+1, questIndex)" 
    matTooltip="{{ratingId+1}}" 
    matTooltipPosition="above"
  > 
    <mat-icon>
      {{ showFirstIcon(i, questIndex) }}
    </mat-icon>
  </button>
  <br><br>
  <!-- 第二组星星 -->
  <button 
    mat-icon-button 
    [color]="color" 
    *ngFor="let ratingId of ratingArr; index as i" 
    [id]="'star_second_' + questIndex + '_' + i" 
    (click)="onClickSecond(i+1, questIndex)" 
    matTooltip="{{ratingId+1}}" 
    matTooltipPosition="above"
  > 
    <mat-icon>
      {{ showSecondIcon(i, questIndex) }}
    </mat-icon>
  </button> 
</li>

内容的提问来源于stack exchange,提问作者gueraini youcef

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 17:55:24