I am using the vmware/clarity
design system and I'm trying to implement dynamic app-level alerts using the dynamic component loading outlined in angular.io. I've followed this pattern before, but I can't seem to get this to work with the alerts coming from Clarity.
app.component.ts
import { AfterViewInit, Component, ComponentFactoryResolver, OnDestroy, ViewChild } from '@angular/core'; import { ClrAlert } from '@clr/angular'; import { AlertsHostDirective } from './directives/alerts-host.directive'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent implements AfterViewInit, OnDestroy { @ViewChild(AlertsHostDirective) alerts: AlertsHostDirective; private interval: NodeJS.Timer; constructor(private _componentFactoryResolver: ComponentFactoryResolver) { } ngAfterViewInit(): void { this.alert(); this.getAlerts(); } ngOnDestroy(): void { clearInterval(this.interval); } private alert() { const componentFactory = this._componentFactoryResolver.resolveComponentFactory(ClrAlert); const viewContainerRef = this.alerts.viewContainerRef; const componentRef = viewContainerRef.createComponent(componentFactory); componentRef.instance.isAppLevel = true; componentRef.changeDetectorRef.detectChanges(); } private getAlerts() { this.interval = setInterval(() => { this.alert(); }, 5000); } }
app.component.html
<clr-main-container> <clr-alerts> <ng-template appAlertsHost></ng-template> <clr-alert clrAlertType="info" [clrAlertAppLevel]="true"> <div class="alert-item"> <span class="alert-text">This is the first app level alert. </span> <div class="alert-actions"> <button class="btn alert-action">Fix</button> </div> </div> </clr-alert> <clr-alert clrAlertType="danger" [clrAlertAppLevel]="true"> <div class="alert-item"> <span class="alert-text">This is a second app level alert.</span> <div class="alert-actions"> <button class="btn alert-action">Fix</button> </div> </div> </clr-alert> </clr-alerts> ...
alerts-host.directive.ts
import { Directive, ViewContainerRef } from '@angular/core'; @Directive({ selector: '[appAlertsHost]' }) export class AlertsHostDirective { constructor(public viewContainerRef: ViewContainerRef) { } }
If I put the directive on the ClrAlerts
component, it works the way it should in that app level alerts are appended after the ClrAlerts
in the DOM. But I want all my app-level alerts to appear inside that component as they come in. In turn, I'd like for the pager component that appears to be updated as well.
Is this possible?