Reputation: 1159
I am working on an Angular(17.x) project where I need to create and manage multiple popup dialogs dynamically. I aim to avoid manually creating separate components, inputs, and outputs for each popup. Instead, I want to use a service to create these dialogs and handle their events dynamically.
I have tried to implement a solution using ViewContainerRef and a custom service to open dialogs. However, the dialogs are not opening as expected, and I am encountering issues with binding inputs and outputs dynamically. Below is my current implementation.
Html file
<button (click)="popupAOpen()">Open Popup A</button>
<button (click)="popupBOpen()">Open Popup B</button>
<button (click)="popupCOpen()">Open Popup C</button>
<ng-template #dialogContainer></ng-template>
component typescript file
import { Component, ViewChild, ViewContainerRef } from '@angular/core';
import { PopupWindowService } from './popup-window.service';
@Component({
selector: 'app-my-page',
templateUrl: './my-page.component.html',
styleUrls: ['./my-page.component.css']
})
export class MyPage{
@ViewChild('dialogContainer', { read: ViewContainerRef }) viewContainerRef!: ViewContainerRef;
inputA1: any = 'exampleA1';
inputA2: any = 'exampleA2';
inputB1: any = 'exampleB1';
inputB2: any = 'exampleB2';
inputC1: any = 'exampleC1';
inputC2: any = 'exampleC2';
constructor(private dialogService: PopupWindowService) {}
popupAOpen() {
this.dialogService.openDialog(
this.viewContainerRef,
PopUpA,
{ isVisible: true, inputA1: this.inputA1, inputA2: this.inputA2 },
{ outputA1: this.outputA1.bind(this), outputA2: this.outputA2.bind(this) }
);
}
popupBOpen() {
this.dialogService.openDialog(
this.viewContainerRef,
PopUpB,
{ isVisible: true, inputB1: this.inputB1, inputB2: this.inputB2 },
{ outputB1: this.outputB1.bind(this), outputB2: this.outputB2.bind(this) }
);
}
popupCOpen() {
this.dialogService.openDialog(
this.viewContainerRef,
PopUpC,
{ isVisible: true, inputC1: this.inputC1, inputC2: this.inputC2 },
{ outputC1: this.outputC1.bind(this), outputC2: this.outputC2.bind(this) }
);
}
outputA1() { /* Handle outputA1 */ }
outputA2() { /* Handle outputA2 */ }
outputB1() { /* Handle outputB1 */ }
outputB2() { /* Handle outputB2 */ }
outputC1() { /* Handle outputC1 */ }
outputC2() { /* Handle outputC2 */ }
}
PopupWindowService
import { Injectable, ComponentRef, ApplicationRef, Injector, ViewContainerRef } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class PopupWindowService {
private dialogRefs: ComponentRef<any>[] = [];
constructor(
private appRef: ApplicationRef,
private injector: Injector
) {}
openDialog(viewContainerRef: ViewContainerRef, component: any, inputs: any, outputs: any = {}): ComponentRef<any> {
const contentRef = viewContainerRef.createComponent(component, { injector: this.injector });
Object.keys(inputs).forEach(inputName => {
contentRef.instance[inputName] = inputs[inputName];
});
const dialogRef = viewContainerRef.createComponent(DialogComponent, { injector: this.injector });
dialogRef.instance.content = contentRef.location.nativeElement;
this.appRef.attachView(dialogRef.hostView);
this.appRef.attachView(contentRef.hostView);
document.body.appendChild((dialogRef.hostView as any).rootNodes[0] as HTMLElement);
this.dialogRefs.push(dialogRef);
Object.keys(outputs).forEach(outputName => {
if (contentRef.instance[outputName]) {
contentRef.instance[outputName].subscribe(outputs[outputName]);
}
});
dialogRef.instance.show();
contentRef.instance.closeDialog.subscribe(() => this.closeDialog(dialogRef, contentRef));
return dialogRef;
}
closeDialog(dialogRef: ComponentRef<any>, contentRef: ComponentRef<any>) {
dialogRef.instance.hide();
this.appRef.detachView(dialogRef.hostView);
this.appRef.detachView(contentRef.hostView);
dialogRef.destroy();
contentRef.destroy();
this.dialogRefs = this.dialogRefs.filter(ref => ref !== dialogRef);
}
}
I have attempted to dynamically create and manage popups using a service, but the dialogs are not opening correctly. I suspect there might be an issue with how I am binding inputs and outputs dynamically.
Specific Questions
Any help or insights would be greatly appreciated!
Upvotes: 1
Views: 187