From 0ffe9c77f2a50315576fd934df11aa3e453e141b Mon Sep 17 00:00:00 2001 From: Justin McGettigan Date: Thu, 17 Feb 2022 04:22:42 -0500 Subject: [PATCH] Fixed ability to use @ Input() dynamic content. (#335) * Fixed ability to use @ Input() dynamic content. * Updated relevant demo code to demonstrate fix. * Added the ability to update ComponentRef data. * Removed static option from ViewChild(). --- src/app/demo/fake/fake.component.html | 7 ++-- src/app/demo/fake/fake.component.ts | 5 ++- src/app/demo/main/main.component.html | 4 +- src/app/demo/main/main.component.ts | 16 ++++++-- .../components/ngx-smart-modal.component.ts | 39 ++++++++++++++----- 5 files changed, 51 insertions(+), 20 deletions(-) diff --git a/src/app/demo/fake/fake.component.html b/src/app/demo/fake/fake.component.html index 5696ea7f..b93de07e 100644 --- a/src/app/demo/fake/fake.component.html +++ b/src/app/demo/fake/fake.component.html @@ -1,3 +1,4 @@ -

Hello {{ name }}

-

I'm a component !

-

Just to say, "Jack" is a template binding value!

+

Hello {{ firstname }} {{ lastname }}

+

I'm a component!

+

"Jack" is a template binding value!

+

"Frost" is an @Input() value!

\ No newline at end of file diff --git a/src/app/demo/fake/fake.component.ts b/src/app/demo/fake/fake.component.ts index 83c8ce25..d03f78ad 100644 --- a/src/app/demo/fake/fake.component.ts +++ b/src/app/demo/fake/fake.component.ts @@ -1,3 +1,4 @@ +import { Input } from '@angular/core'; import { Component, OnInit } from '@angular/core'; @Component({ @@ -6,8 +7,8 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./fake.component.scss'] }) export class FakeComponent implements OnInit { - - public name = 'Jack'; + firstname: string = 'Jack'; + @Input() lastname: string; constructor() { } diff --git a/src/app/demo/main/main.component.html b/src/app/demo/main/main.component.html index edb6fae9..778221b3 100644 --- a/src/app/demo/main/main.component.html +++ b/src/app/demo/main/main.component.html @@ -1,7 +1,7 @@

Hello {{ name }}

-

I'm TemplateRef content !

-

Just to say, "Bobby" is a template binding value!

+

I'm TemplateRef content!

+

"Bobby" is a template binding value!

diff --git a/src/app/demo/main/main.component.ts b/src/app/demo/main/main.component.ts index 8d767416..6c9e876d 100644 --- a/src/app/demo/main/main.component.ts +++ b/src/app/demo/main/main.component.ts @@ -93,9 +93,19 @@ export class MainComponent implements AfterViewInit { this.ngxSmartModalService.create('dynamicModal1', 'Hello, I\'m a simple text !').open(); - this.ngxSmartModalService.create('dynamicModal2', FakeComponent, opts).open(); - - this.ngxSmartModalService.create('dynamicModal3', this.tpl, opts).open(); + this.ngxSmartModalService.create('dynamicModal2', this.tpl, opts).open(); + + this.ngxSmartModalService.create('dynamicModal3', FakeComponent, opts).open(); + + const modal = this.ngxSmartModalService + .create('dynamicModal4', FakeComponent, opts) + .setData({ lastname: "Frost" }) + .open(); + + setTimeout(() => { + modal.setData({ lastname: "Frost (Updated)" }, true); + }, 1000); + } } diff --git a/src/ngx-smart-modal/src/components/ngx-smart-modal.component.ts b/src/ngx-smart-modal/src/components/ngx-smart-modal.component.ts index 3e0b13d1..3eb6fb92 100644 --- a/src/ngx-smart-modal/src/components/ngx-smart-modal.component.ts +++ b/src/ngx-smart-modal/src/components/ngx-smart-modal.component.ts @@ -5,6 +5,7 @@ import { Component, ComponentFactory, ComponentFactoryResolver, + ComponentRef, ElementRef, EventEmitter, HostListener, @@ -17,6 +18,7 @@ import { QueryList, Renderer2, Type, + ViewChild, ViewChildren, ViewContainerRef } from '@angular/core'; @@ -100,11 +102,12 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy, AfterViewInit public createFrom = 'html'; private _data: any; + private _componentRef: ComponentRef; @ViewChildren('nsmContent') private nsmContent: QueryList; @ViewChildren('nsmDialog') public nsmDialog: QueryList; @ViewChildren('nsmOverlay') private nsmOverlay: QueryList; - @ViewChildren('dynamicContent', { read: ViewContainerRef }) dynamicContentContainer: QueryList; + @ViewChild('dynamicContent', { read: ViewContainerRef }) private dynamicContentContainer: ViewContainerRef; constructor( private _renderer: Renderer2, @@ -127,9 +130,6 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy, AfterViewInit if (this.contentComponent) { const factory = this.componentFactoryResolver.resolveComponentFactory(this.contentComponent); this.createDynamicContent(this.dynamicContentContainer, factory); - this.dynamicContentContainer.changes.subscribe((contentViewContainers: QueryList) => { - this.createDynamicContent(contentViewContainers, factory); - }); } } @@ -244,6 +244,7 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy, AfterViewInit public setData(data: any, force?: boolean): NgxSmartModalComponent { if (!this.hasData() || (this.hasData() && force)) { this._data = data; + this.assignModalDataToComponentData(this._componentRef); this.onDataAdded.emit(this._data); this.markForCheck(); } @@ -255,6 +256,7 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy, AfterViewInit * Retrieve the data attached to the modal instance */ public getData(): any { + this.assignComponentDataToModalData(this._componentRef); return this._data; } @@ -367,11 +369,28 @@ export class NgxSmartModalComponent implements OnInit, OnDestroy, AfterViewInit /** * Creates content inside provided ViewContainerRef */ - private createDynamicContent(changes: QueryList, factory: ComponentFactory): void { - changes.forEach((viewContainerRef: ViewContainerRef) => { - viewContainerRef.clear(); - viewContainerRef.createComponent(factory); - this.markForCheck(); - }); + private createDynamicContent(viewContainerRef: ViewContainerRef, factory: ComponentFactory): void { + viewContainerRef.clear(); + this._componentRef = viewContainerRef.createComponent(factory); + this.assignModalDataToComponentData(this._componentRef); + this.markForCheck(); + } + + /** + * Assigns the modal data to the ComponentRef instance properties + */ + private assignModalDataToComponentData(componentRef: ComponentRef): void { + if(componentRef) { + Object.assign(componentRef.instance, this._data); + } + } + + /** + * Assigns the ComponentRef instance properties to the modal data object + */ + private assignComponentDataToModalData(componentRef: ComponentRef): void { + if(componentRef) { + Object.assign(this._data, componentRef.instance); + } } }