Reputation: 639
I'm making a modal and I made it a component <modal-component>
.
Inside <modal-component>
I have a close button. I want to destroy <modal-component>
when I click that button.
Something like this:
<button (click)="closeModal()">Close</button>
I also could make the close button a component. Something like <close-modal>
if neccesary.
Is this possible?
Upvotes: 7
Views: 21786
Reputation: 1810
There is one other trick:
import { ViewContainerRef } from '@angular/core';
constructor(private viewContainerRef: ViewContainerRef) {}
...
private selfClose() {
this.viewContainerRef
.element
.nativeElement
.parentElement
.removeChild(this.viewContainerRef.element.nativeElement);
}
NOTE: It'll make the component removed / disappear, but the ngOnDestroy hook isn't called, the component is NOT fully destroyed until the parent is destroyed.
Upvotes: 2
Reputation: 21658
Create a ModalControlService that has a boolean BehaviorSubject
import { Injectable } from '@angular/core';
import {BehaviorSubject} from 'rxjs';
@Injectable()
export class ModalControlService {
modalOpen$ = new BehaviorSubject<boolean>(false);
open() {
this.modalOpen$.next(true);
}
close() {
this.modalOpen$.next(false);
}
}
Provide the service from the component you want to host the modal from so you get the same instance of the service in your host component and your modal component.
In the host component
import { Component } from '@angular/core';
import { ModalControlService } from './modal-control.service';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
providers: [ ModalControlService ]
})
export class AppComponent {
modalOpen$ = this.modalControlService.modalOpen$;
constructor(private modalControlService: ModalControlService) {}
openModal() {
this.modalControlService.open();
}
}
and in the template
<modal-component *ngIf="modalOpen$ | async"></modal-component>
Then in the modal component
import { Component, OnInit } from '@angular/core';
import { ModalControlService } from '../modal-control.service';
@Component({
selector: 'modal-component',
templateUrl: './modal.component.html',
styleUrls: ['./modal.component.css']
})
export class ModalComponent {
constructor(private modalControlService: ModalControlService) { }
closeModal() {
this.modalControlService.close();
}
}
StackBlitz https://stackblitz.com/edit/angular-gc1ugw?file=src%2Fapp%2Fapp.component.ts
Upvotes: 3
Reputation: 41581
If you are using ngx-bootstrap
modal dialog, by default the component is destroyed on close
Typescript
openModal() {
this.modalRef = this.modalService.show(SomeComponent, {
initialState: {
title: 'Modal title',
data: {}
}
});
}
HTML
<div (click)="openModal()" class="btn btn-success"> Modal Component</div>
Upvotes: 1
Reputation: 10157
Parent must destroy its child. So you can send an event from child
@Output()
onClose: EventEmitter<boolean> = new EventEmitter();
...
closeModal() {
this.onClose.emit(true);
}
And capture the event in parent:
<modal-component *ngIf="showModal" (onClose)="modalClosed($event)">
And parent component:
modalClosed(isClosed) {
this.showModal = false;
}
*ngIf
directive will take care of the rest.
Might be a mistake or two, I'm on a mobile...
Upvotes: 6