ContentChildren with multiple content types

The answer from @3xGuy is correct but the forwardRef(() => {}) is not required unless the type being provided is defined after the decorator or the decorated class see this Angular In Depth post

Note this approach can be used for ContentChildren or ViewChildren, below I use ViewChildren

item.ts

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

export class Item {
  color = '';
}

@Directive({
  selector: '[blueItem]',
  providers: [{ provide: Item, useExisting: BlueItemDirective }],
})
export class BlueItemDirective { // 'extends Item' is optional
  color = 'blue';
}

@Directive({
  selector: '[redItem]',
  providers: [{ provide: Item, useExisting: RedItemDirective }],
})
export class RedItemDirective { // 'extends Item' is optional
  color = 'red';
}

app.component.ts

import { Component, ViewChildren, QueryList } from '@angular/core';

import { Item } from './item';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Multiple View Child Types';

  // Note we query for 'Item' here and not `RedItemDirective'
  // or 'BlueItemDirective' but this query selects both types
  @ViewChildren(Item) viewItems: QueryList<Item>;

  itemColors: string[] = [];

  ngAfterViewInit() {
    this.itemColors = this.viewItems.map(item => item.color);
  }
}

app.component.html

<div redItem>Item</div>
<div blueItem>Item</div>
<div blueItem>Item</div>
<div blueItem>Item</div>
<div redItem>Item</div>

<h2>Colors of the above directives</h2>
<ul>
  <li *ngFor="let color of itemColors">{{color}}</li>
</ul>

Here is a StackBlitz showing this behavior in action.

Tags:

Angular