/
render-app.directive.ts
55 lines (47 loc) · 1.49 KB
/
render-app.directive.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import {
Directive,
Input,
NgModuleRef,
OnDestroy,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
import { LoadableApp } from '@angular-dream/app-utils';
import { Router } from '@angular/router';
import { Store } from '@ngrx/store';
@Directive({
selector: '[renderApp]',
})
export class RenderAppDirective implements OnDestroy {
currentNgModuleRef?: NgModuleRef<unknown>;
@Input() set renderApp(ngModuleRef: NgModuleRef<LoadableApp> | null) {
if (!ngModuleRef || this.currentNgModuleRef) {
return;
}
this.currentNgModuleRef = ngModuleRef;
const injector = ngModuleRef.injector;
const router = ngModuleRef.injector.get(Router, null);
if (!ngModuleRef.instance.EntryComponent) {
throw Error(
`Cannot load app: ${ngModuleRef} cause the EntryComponent is not defined in the Module.`
);
}
const componentRef = ngModuleRef.componentFactoryResolver
.resolveComponentFactory(ngModuleRef.instance.EntryComponent)
.create(injector);
this.viewContainerRef.insert(componentRef.hostView);
router?.initialNavigation();
componentRef.changeDetectorRef.detectChanges();
}
constructor(
private readonly templateRef: TemplateRef<unknown>,
private readonly viewContainerRef: ViewContainerRef
) {}
ngOnDestroy() {
if (this.currentNgModuleRef) {
this.currentNgModuleRef.injector.get(Store, null)?.complete();
this.currentNgModuleRef.destroy();
this.currentNgModuleRef = undefined;
}
}
}