在ngFor循环中为元素动态添加类

时间:2018-11-09 18:15:07

标签: angular typescript

我有以下模板:

<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
    }
  }

如何在*ngFor循环中动态地将CSS类添加/删除到事件发射器?

我需要一次将类添加到一个元素。

1 个答案:

答案 0 :(得分:3)

基本上有两种方法可以实现您要在此处实现的目标。

方法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

正如其他人所提到的,如果您愿意发送一些属性作为发出事件的一部分来决定是否应用该类,请从您的子组件中进行操作,然后传递更新后的{{1} },作为发射的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' });
  }

  ...

}

这是一个Working Sample StackBlitz,上面有两个给您推荐的方式。