Creating modal component in angular

Discussão em 'Angular' iniciado por Hesam Akbari, Fevereiro 19, 2025.

  1. Hesam Akbari

    Hesam Akbari Guest

    considering the following code as it's my custom ui-modal.component

    import { CommonModule } from '@angular/common';
    import { ChangeDetectionStrategy, Component, inject, input, output, signal, viewChild } from '@angular/core';
    import { UIModalOptions } from './modal.model';
    import { ModalService } from './modal.service';

    @Component({
    selector: 'ui-modal',
    standalone: true,
    imports: [CommonModule],
    templateUrl: './ui-modal.component.html',
    styleUrl: './ui-modal.component.css',
    changeDetection: ChangeDetectionStrategy.OnPush
    })
    export class UiModalComponent {
    private readonly modalService = inject(ModalService);

    // Inputs
    title = input<string>();
    body = input<string>();
    bodyClass = input<string>();
    showHeaderCloseButton = input<boolean>(true);
    showFooter = input<boolean>(true);

    // Outputs
    closed = output<void>();

    // Template reference
    readonly content = viewChild('modalContent');
    useAsTemplate = input(true);
    loadData = signal(false);

    /**
    * Opens the modal with optional configuration.
    * @param options - Optional configuration for the modal.
    */
    open(options?: UIModalOptions) {
    return this.modalService.open(this.content(), options);
    }

    /**
    * Closes the modal and emits the close event.
    */
    close(): void {
    this.closed.emit();
    this.modalService.dismissAll();
    }
    }


    <ng-template #modalContent>
    <div class="modal-header d-flex justify-content-between">
    <ng-content select="[modal-header]" />
    @if (title()) {
    <span class="modal-title">{{ title() }}</span>
    }
    @if (showHeaderCloseButton()) {
    <button type="button" class="btn-close cup me-0 ms-auto p-0" aria-label="Close" (click)="close()">
    <span aria-hidden="true"></span>
    </button>
    }
    </div>
    <div class="modal-body {{ bodyClass() }}">
    @if (body()) {
    <div class="text-justify">
    <p>{{ body() }}</p>
    </div>
    }
    <ng-content select="[modal-body]" />
    </div>
    @if (showFooter()) {
    <div class="modal-footer">
    <ng-content select="[modal-footer]" />
    </div>
    }
    </ng-template>


    And the following code example is showing how I am using it in other components

    <ui-modal title="مدیریت فیلترها" bodyClass="p-0" [showFooter]="false">
    <div modal-body class="h-100">
    <filter-management class="overflow-hidden" (closeModal)="onFilterManagementClose()" />
    </div>
    </ui-modal>


    As you can see in the html of the ui-modal component, I am using ng-template to defer content creation.

    In fact, by the above structure, I expected the modal content (like filter-management component) is only instantiated when I open the modal by calling the open method(), But It is not working.

    Even though the filter-management component is hidden initially, its constructor and Angular lifecycle hooks (like ngOnInit) are called immediately, before I actually open the modal with

    Thanks for any help

    Continue reading...

Compartilhe esta Página