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.