简体   繁体   中英

How can I destroy an Angular component?

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?

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...

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

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>

Stackblitz

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM