import { Directive , ElementRef , EventEmitter , OnDestroy , OnInit , Output , ChangeDetectorRef , ViewContainerRef , TemplateRef , ContentChild , ContentChildren , AfterContentInit , Input } from '@angular/core' ; import { ComponentLoaderService } from './component-loader.service' ; import { LazyCmpLoadedEvent } from './lazy-cmp-loaded-event' ; @ Directive ( { selector : '[ngxLazyEl]' } ) export class LazyLoadDirective implements OnInit , OnDestroy { @ Output ( ) loaded = new EventEmitter < LazyCmpLoadedEvent > ( ) ; constructor ( private elementRef , private componentLoader , private cd , private vcr , private template ) { } ngOnInit ( ) { let nodeTags ; if ( ! nodeTags ) { const template = this . template . createEmbeddedView ( { } ) ; if ( template . rootNodes [ 0 ] . children . length > 0 ) { nodeTags = [ ... template . rootNodes [ 0 ] . children ] . map ( x => x . tagName . toLowerCase ( ) ) ; } else { nodeTags = [ template . rootNodes [ 0 ] . tagName . toLowerCase ( ) ] ; } } if ( ! nodeTags ) { throw new Error ( `Unable to automatically determine the dynamic element selectors. Alternatively you can pass them in via the *ngxLazyEl="['my-lazy-el']"` ) ; } this . componentLoader . loadContainedCustomElements ( nodeTags ) . subscribe ( elements => { this . vcr . clear ( ) ; this . vcr . createEmbeddedView ( this . template ) ; let domInstance = null ; if ( this . elementRef . nativeElement . parentElement ) { domInstance = this . elementRef . nativeElement . parentElement . querySelector ( elements [ 0 ] . selector ) ; } this . notifyComponentLoaded ( { selector : nodeTags [ 0 ] , componentInstance : domInstance } ) ; } ) ; } private isIvyMode ( ) { return ( this . template as any ) . _declarationTContainer ; } private notifyComponentLoaded ( lazyCmpEv ) { this . loaded . emit ( { selector : lazyCmpEv . selector , componentInstance : lazyCmpEv . componentInstance } ) ; } ngOnDestroy ( ) { console . log ( 'lazy load destroyed' ) ; } }