Я делал это раньше с элементом Angular Material mat-select
, используя @ContentChildren и ng-template.
Рабочий пример здесь
dropdown.ts
import { Component, OnInit, Input, ViewEncapsulation, Output, EventEmitter, ViewChild, ContentChildren, QueryList , TemplateRef} from '@angular/core';
import { MatSelectChange, MatSelect } from '@angular/material/select';
// Template Sections
@Component({
selector: 'custom-dropdown-item',
template: '<ng-template #content><ng-content></ng-content></ng-template>'
})
export class CustomDropdownItemsComponent {
@ViewChild('content') content: any;
@Input() value: any;
@Input() width: string;
@Input() height: string;
@Output() click: EventEmitter<any> = new EventEmitter();
onClick() {
this.click.emit(this.value);
}
}
@Component({
selector: 'custom-dropdown',
templateUrl: './custom-dropdown.component.html',
styleUrls: ['./custom-dropdown.component.scss']
})
export class CustomDropdownComponent implements OnInit {
@ViewChild('matSelect') matSelect: MatSelect;
@Output() valueChange: EventEmitter<MatSelectChange> = new EventEmitter<MatSelectChange>();
@Output() openedChange: EventEmitter<boolean> = new EventEmitter<boolean>();
@Input() value: any;
@Input() items: string[];
@Input() placeholder: string;
@Input() dropdownTitle: string;
@Input() addDynamicContent: boolean = false;
@Input() compareWith: Function;
defaultCompareWithFn: Function = function () { };
selectedIndex = -1;
@ContentChildren(CustomDropdownItemsComponent)
ddItems:QueryList<CustomDropdownItemsComponent>;
constructor() { }
ngOnInit() {
}
valueChanged(event: MatSelectChange) {
this.valueChange.emit(event.value);
}
}
dropdown.html
<mat-select #matSelect [(value)]="value" (selectionChange)="valueChanged($event)">
<mat-option style="width:100px" [value]="0">
<h1 style="color:red">I'm content = 0</h1>
</mat-option>
<mat-option [style.width]="ddlItem.width" [value]="i+1" *ngFor="let ddlItem of ddItems; let i = index">
<ng-container [ngTemplateOutlet]="ddlItem.content"></ng-container>
</mat-option>
</mat-select>
Передача пользовательских элементов:
<div class="mat-app-background basic-container" style="width:200px; padding:0; margin:0">
<custom-dropdown [addDynamicContent]="true" [(value)]="selected">
<custom-dropdown-item width="100px">
<span style="color:green">I'm dynamic content = 1</span>
</custom-dropdown-item>
<custom-dropdown-item width="100px">
<p style="color:blue">I'm dynamic content = 2</p>
</custom-dropdown-item>
</custom-dropdown>
</div>
<div>
Selected: {{ selected }}
</div>