]>
Commit | Line | Data |
---|---|---|
1 | import { | |
2 | ApplicationRef, | |
3 | ComponentRef, | |
4 | createComponent, | |
5 | EmbeddedViewRef, | |
6 | Injectable, | |
7 | Injector, | |
8 | OnChanges, | |
9 | SimpleChange, | |
10 | SimpleChanges, | |
11 | Type | |
12 | } from '@angular/core' | |
13 | import { objectKeysTyped } from '@shared/core-utils' | |
14 | ||
15 | @Injectable() | |
16 | export class DynamicElementService { | |
17 | ||
18 | constructor ( | |
19 | private injector: Injector, | |
20 | private applicationRef: ApplicationRef | |
21 | ) { } | |
22 | ||
23 | createElement <T> (ofComponent: Type<T>) { | |
24 | const div = document.createElement('div') | |
25 | ||
26 | const component = createComponent(ofComponent, { | |
27 | environmentInjector: this.applicationRef.injector, | |
28 | elementInjector: this.injector, | |
29 | hostElement: div | |
30 | }) | |
31 | ||
32 | return component | |
33 | } | |
34 | ||
35 | injectElement <T> (wrapper: HTMLElement, componentRef: ComponentRef<T>) { | |
36 | const hostView = componentRef.hostView as EmbeddedViewRef<any> | |
37 | ||
38 | this.applicationRef.attachView(hostView) | |
39 | wrapper.appendChild(hostView.rootNodes[0]) | |
40 | } | |
41 | ||
42 | setModel <T> (componentRef: ComponentRef<T>, attributes: Partial<T>) { | |
43 | const changes: SimpleChanges = {} | |
44 | ||
45 | for (const key of objectKeysTyped(attributes)) { | |
46 | const previousValue = componentRef.instance[key] | |
47 | const newValue = attributes[key] | |
48 | ||
49 | componentRef.instance[key] = newValue | |
50 | changes[key as string] = new SimpleChange(previousValue, newValue, previousValue === undefined) | |
51 | } | |
52 | ||
53 | const component = componentRef.instance | |
54 | if (typeof (component as unknown as OnChanges).ngOnChanges === 'function') { | |
55 | (component as unknown as OnChanges).ngOnChanges(changes) | |
56 | } | |
57 | ||
58 | componentRef.changeDetectorRef.detectChanges() | |
59 | } | |
60 | } |