Table of Contents
Creating a custom modal service in Angular allows developers to implement reusable dialog components that enhance user experience and maintainability. This guide walks you through building a flexible modal service from scratch.
Understanding the Need for a Custom Modal Service
In Angular applications, dialogs and modals are common UI elements used for confirmations, forms, or alerts. While Angular Material provides built-in dialog components, customizing your own modal service offers greater flexibility and control over appearance and behavior.
Implementing the Modal Service
Start by creating a new service that manages the opening and closing of modal components. This service will handle dynamic component loading and communication between components.
Creating the Modal Service
Generate a new service using Angular CLI:
ng generate service services/modal
Next, implement methods to open and close modals, utilizing Angular’s ComponentFactoryResolver and ViewContainerRef for dynamic component loading.
Sample Modal Service Code
import { Injectable, ComponentRef, ComponentFactoryResolver, ApplicationRef, Injector } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ModalService {
private modalRef: ComponentRef | null = null;
constructor(
private resolver: ComponentFactoryResolver,
private appRef: ApplicationRef,
private injector: Injector
) {}
open(component: any, data?: any): void {
if (this.modalRef) {
this.close();
}
const factory = this.resolver.resolveComponentFactory(component);
this.modalRef = factory.create(this.injector);
if (data) {
Object.assign(this.modalRef.instance, data);
}
this.appRef.attachView(this.modalRef.hostView);
const domElem = (this.modalRef.hostView as any).rootNodes[0] as HTMLElement;
document.body.appendChild(domElem);
}
close(): void {
if (this.modalRef) {
this.appRef.detachView(this.modalRef.hostView);
this.modalRef.destroy();
this.modalRef = null;
}
}
}
Creating a Reusable Modal Component
Design a generic modal component that can display various content and handle user interactions. This component will be dynamically created by the modal service.
Sample Modal Component
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-custom-modal',
template: `
`,
styles: [`
.modal-backdrop {
position: fixed;
top: 0; left: 0;
width: 100%; height: 100%;
background: rgba(0,0,0,0.5);
display: flex; justify-content: center; align-items: center;
}
.modal-content {
background: #fff;
padding: 20px;
border-radius: 8px;
min-width: 300px;
}
`]
})
export class CustomModalComponent {
@Input() title: string = 'Modal Title';
@Output() closeEvent = new EventEmitter();
close() {
this.closeEvent.emit();
}
onBackdropClick() {
this.close();
}
}
Using the Modal Service in Your Application
Inject the modal service into your component and trigger the open method to display the modal with desired content.
Example Usage
import { Component } from '@angular/core';
import { ModalService } from './services/modal.service';
import { CustomModalComponent } from './components/custom-modal.component';
@Component({
selector: 'app-root',
template: `
`
})
export class AppComponent {
constructor(private modalService: ModalService) {}
openModal() {
this.modalService.open(CustomModalComponent, { title: 'Reusable Dialog' });
}
}
This setup creates a flexible modal system that can be reused throughout your Angular application, improving consistency and code maintainability.