I possess the capability to dynamically generate components:
import { Component, ComponentFactory, ComponentFactoryResolver, ComponentRef, OnInit, ViewChild, ViewContainerRef } from '@angular/core';
import { FilterComponent } from '../filter/filter.component';
export enum FilterType {
DateRangeFilter, SensorSelectFilter
}
@Component({
selector: 'app-filter-collection',
templateUrl: './filter-collection.component.html',
styleUrls: ['./filter-collection.component.css']
})
export class FilterCollectionComponent implements OnInit {
filters: Array<ComponentRef<FilterComponent>> = [];
@ViewChild("messagecontainer", { read: ViewContainerRef }) entry!: ViewContainerRef;
constructor(private resolver: ComponentFactoryResolver) { }
onAddDateRangeFilter() {
const factory: ComponentFactory<FilterComponent> = this.resolver.resolveComponentFactory(FilterComponent);
const filter = this.entry.createComponent<FilterComponent>(factory);
filter.instance.filter = FilterType.DateRangeFilter;
this.filters.push(filter);
}
onAddSensorSelectFilter() {
const factory: ComponentFactory<FilterComponent> = this.resolver.resolveComponentFactory(FilterComponent);
const filter = this.entry.createComponent<FilterComponent>(factory);
filter.instance.filter = FilterType.SensorSelectFilter;
this.filters.push(filter);
}
ngOnInit(): void {
}
}
whereas FilterComponent
is structured as follows:
@Component({
selector: 'app-filter',
templateUrl: './filter.component.html',
styleUrls: ['./filter.component.css']
})
export class FilterComponent {
@Input() filter!: FilterType;
_FilterType = FilterType;
range = new FormGroup({
start: new FormControl(),
end: new FormControl()
});
constructor() {
}
ngOnInit(): void {
}
}
with the following HTML structure:
<div *ngIf="filter === _FilterType.SensorSelectFilter">
<mat-form-field class="sensorFilter" appearance="fill">
<mat-label>Cars</mat-label>
<select matNativeControl required>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
</mat-form-field>
</div>
<div *ngIf="filter === _FilterType.DateRangeFilter">
<mat-form-field class="dateFilter" appearance="fill">
<mat-label>Enter a date range to filter data</mat-label>
<mat-date-range-input [formGroup]="range" [rangePicker]="picker">
<input matStartDate formControlName="start" placeholder="Start date">
<input matEndDate formControlName="end" placeholder="End date">
</mat-date-range-input>
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-date-range-picker #picker></mat-date-range-picker>
<mat-error *ngIf="range.controls.start.hasError('matStartDateInvalid')">Invalid start date</mat-error>
<mat-error *ngIf="range.controls.end.hasError('matEndDateInvalid')">Invalid end date</mat-error>
</mat-form-field>
</div>
Still, I am encountering difficulties in rendering these components in HTML. I tried including the following code snippet in FilterCollectionComponent.html
:
<div *ngFor="let filter of filters">
<app-filter [filter]="filter.instance.filter"></app-filter>
</div>
Yet, this approach seems to be ineffective.
Any insights on why this method is not working properly? Your assistance is highly appreciated!