Skip to content

Commit c7e5b2a

Browse files
author
GrzegorzTokarz
authored
Merge pull request #1 from GrzegorzTokarz/feature/dynamic-content
feature/dynamic-content: add possibility to render dynamic components
2 parents aa5a198 + 03d7691 commit c7e5b2a

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

src/ngx-smart-modal/src/components/ngx-smart-modal.component.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
22
import {
3-
Input,
4-
Output,
5-
OnInit,
6-
OnDestroy,
7-
Renderer2,
3+
AfterViewInit,
4+
ChangeDetectorRef,
85
Component,
6+
ComponentFactoryResolver,
7+
ElementRef,
98
EventEmitter,
109
HostListener,
11-
ChangeDetectorRef,
12-
ViewChildren,
13-
ElementRef,
14-
QueryList,
1510
Inject,
16-
PLATFORM_ID
11+
Input,
12+
OnDestroy,
13+
OnInit,
14+
Output,
15+
PLATFORM_ID,
16+
QueryList,
17+
Renderer2,
18+
Type,
19+
ViewChildren,
20+
ViewContainerRef
1721
} from '@angular/core';
1822

1923
import { NgxSmartModalConfig } from '../config/ngx-smart-modal.config';
@@ -33,7 +37,9 @@ import { NgxSmartModalConfig } from '../config/ngx-smart-modal.config';
3337
[attr.aria-describedby]="ariaDescribedBy">
3438
<div class="nsm-content" #nsmContent>
3539
<div class="nsm-body">
40+
<ng-template #dynamicContent></ng-template>
3641
<ng-content></ng-content>
42+
3743
</div>
3844
<button type="button" *ngIf="closable" (click)="close()" aria-label="Close" class="nsm-dialog-btn-close">
3945
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 512 512"
@@ -53,7 +59,7 @@ import { NgxSmartModalConfig } from '../config/ngx-smart-modal.config';
5359
</div>
5460
`
5561
})
56-
export class NgxSmartModalComponent implements OnInit, OnDestroy {
62+
export class NgxSmartModalComponent implements OnInit, OnDestroy, AfterViewInit {
5763
@Input() public closable: boolean = true;
5864
@Input() public escapable: boolean = true;
5965
@Input() public dismissable: boolean = true;
@@ -81,7 +87,7 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy {
8187
@Output() public onEscape: EventEmitter<any> = new EventEmitter();
8288
@Output() public onDataAdded: EventEmitter<any> = new EventEmitter();
8389
@Output() public onDataRemoved: EventEmitter<any> = new EventEmitter();
84-
90+
public contentComponent: Type<Component>;
8591
public layerPosition: number = 1041;
8692
public overlayVisible: boolean = false;
8793
public openedClass: boolean = false;
@@ -93,12 +99,14 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy {
9399
@ViewChildren('nsmContent') private nsmContent: QueryList<ElementRef>;
94100
@ViewChildren('nsmDialog') public nsmDialog: QueryList<ElementRef>;
95101
@ViewChildren('nsmOverlay') private nsmOverlay: QueryList<ElementRef>;
102+
@ViewChildren('dynamicContent', { read: ViewContainerRef }) dynamicContent: QueryList<ViewContainerRef>;
96103

97104
constructor(
98105
private _renderer: Renderer2,
99106
private _changeDetectorRef: ChangeDetectorRef,
100107
@Inject(DOCUMENT) private _document: any,
101-
@Inject(PLATFORM_ID) private _platformId: any
108+
@Inject(PLATFORM_ID) private _platformId: any,
109+
private componentFactoryResolver: ComponentFactoryResolver
102110
) { }
103111

104112
public ngOnInit() {
@@ -109,6 +117,16 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy {
109117
this._sendEvent('create');
110118
}
111119

120+
public ngAfterViewInit(): void {
121+
if (this.dynamicContent && this.contentComponent) {
122+
const factory = this.componentFactoryResolver.resolveComponentFactory(this.contentComponent);
123+
const viewContainerRef: ViewContainerRef = this.dynamicContent.first;
124+
viewContainerRef.clear();
125+
viewContainerRef.createComponent(factory);
126+
this.markForCheck();
127+
}
128+
}
129+
112130
public ngOnDestroy() {
113131
this._sendEvent('delete');
114132
}
@@ -329,7 +347,7 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy {
329347
};
330348

331349
const event = new CustomEvent(NgxSmartModalConfig.prefixEvent + name, { detail: data });
332-
350+
333351
return window.dispatchEvent(event);
334352
}
335353

src/ngx-smart-modal/src/services/ngx-smart-modal.service.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,10 @@ export class NgxSmartModalService {
235235

236236
const componentRef = componentFactory.create(this._injector, ngContent);
237237

238+
if (content instanceof Type) {
239+
componentRef.instance.contentComponent = content;
240+
}
241+
238242
componentRef.instance.identifier = id;
239243
componentRef.instance.createFrom = 'service';
240244

@@ -421,7 +425,7 @@ export class NgxSmartModalService {
421425
* Resolve content according to the types
422426
* @param content The modal content ( string, templateRef or Component )
423427
*/
424-
private _resolveNgContent<T>(content: Content<T>) {
428+
private _resolveNgContent<T>(content: Content<T>): any[][] | Text[][] {
425429
if (typeof content === 'string') {
426430
const element = this._document.createTextNode(content);
427431
return [[element]];
@@ -433,10 +437,7 @@ export class NgxSmartModalService {
433437
return [viewRef.rootNodes];
434438
}
435439

436-
const factory = this._componentFactoryResolver.resolveComponentFactory(content);
437-
const componentRef = factory.create(this._injector);
438-
439-
return [[componentRef.location.nativeElement], [this._document.createTextNode('')]];
440+
return [];
440441
}
441442

442443
/**

0 commit comments

Comments
 (0)