我有以下模板:

<app-subscriber
  *ngFor="let stream of streams"
  [stream]="stream"
  [session]="session"
  (speakEvents)='onSpeakEvent($event)'>
</app-subscriber>

父组件侦听来自speakEvents的事件,如下所示:
onSpeakEvent(event: any) {
    if (event.type === 'speaking') {
      this.spotlightSubscriber = event.emitter;
      //The component emitting the event, from the ngFor repeat list.
      //Add class to this.spotlightSubscriber
    }
    else if (event.type === 'stopped_speaking') {
      //Remove class to this.spotlightSubscriber
    }
  }

如何动态地向事件发射器添加/删除css类,它处于*ngFor循环中?
我需要一次将类添加到一个元素中。

最佳答案

基本上有两种方法可以达到你想要达到的目标。
评价1:
创建一个属性(indexToAppendClassTo)来跟踪要对其应用类的索引。当事件由子组件发出时,请在此indexToAppendClassTo列表中添加或移除发出流的索引。并基于此indexToAppendClassTo列表中流的索引的存在应用该类。
课堂上:

import { Component } from '@angular/core';

@Component({...})
export class AppComponent {
  ...
  indexToAppendClassTo: any[] = [];

  onSpeakEvent(event: any, index) {
    // Approach 1
    if (event.type === 'speaking') {
      this.spotlightSubscriber = event.emitter;
      if(this.indexToAppendClassTo.indexOf(index) === -1)
        this.indexToAppendClassTo.push(index);
    } else if (event.type === 'stopped_speaking') {
      if(this.indexToAppendClassTo.indexOf(index) > -1)
        this.indexToAppendClassTo.splice(index, 1);
    }
  }
}

在模板中:
<app-subscriber
  *ngFor="let stream of streams; let i = index;"
  [stream]="stream"
  [session]="session"
  (speakEvents)='onSpeakEvent($event, i)'
  [ngClass]="indexToAppendClassTo.includes(i) ? 'color' : ''">
</app-subscriber>

方法2
如其他人所述,如果您愿意将某些属性作为决定是否应用该类的已发出事件的一部分发送,则从子组件执行此操作,然后将子组件中更新的stream作为已发出的$event数据传递。这样您就不必不必要地管理indexToAppendClassTo列表:
在父组件类中:
import { Component } from '@angular/core';

@Component({...})
export class AppComponent {
  ...

  onSpeakEvent(event: any, index) {
    // Approach 2
    const indexOfElement = this.streams.findIndex(strem => strem.name === event.name);
    this.streams[indexOfElement] = { ...event };
  }
}

在父组件模板中:
<app-subscriber
  *ngFor="let stream of streams"
  [stream]="stream"
  [session]="session"
  (speakEvents)='onSpeakEvent($event)'
  [ngClass]="stream.type === 'speaking' ? 'color': ''">
</app-subscriber>

在子组件类中:
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-subscriber',
  templateUrl: './subscriber.component.html',
  styleUrls: ['./subscriber.component.css']
})
export class SubscriberComponent implements OnInit {

  @Input() stream;
  @Input() session;
  @Output() speakEvents: EventEmitter<any> = new EventEmitter<any>();

  ...

  onClick() {
    this.speakEvents.emit({ ...this.stream, type: 'type of the stream here' });
  }

  ...

}

在子组件模板中:
<button (click)="onClick()">{{stream.name}}</button>

这里有一个Working Sample StackBlitz和两个通知给你的裁判。

10-06 15:06