简体   繁体   中英

Angular - *ngComponentOutlet - destroy Component

I use a *ngComponentOutlet structural directive in order to display a dynamic component. This dynamic component must be displayed based on some conditions .

For example, if a certain route is matched, the component (a search form) should be displayed. Else, it should not be displayed.

I've used the following code:

 <ng-container *ngIf="searchComponent">
  <ng-container *ngComponentOutlet="searchComponent"></ng-container>
 </ng-container>

where:

import {SearchComponent} from '....';

public searchComponent: Type<any> | null; 
...

show(): void {
  this.searchComponent = SearchComponent;
}
 
hide(): void {
  this.searchComponent = null;
}

This works, but using the code above, when hiding the component, the ngOnDestroy() from SearchComponent is never called.

In Angular Documentation ( https://angular.io/api/common/NgComponentOutlet ), I've found that:

NgComponentOutlet requires a component type, if a falsy value is set the view will clear and any existing component will get destroyed.

So, I've tried to use a boolean, like this:

<ng-container *ngComponentOutlet="shouldShow && searchComponent"></ng-container>

and

import {SearchComponent} from '....';

public searchComponent: Type<any> = SearchComponent; 
...

show(): void {
  this.shouldShow = true;
}
 
hide(): void {
  this.shouldShow = false;
}

This works fine for a Stackblitz demo: https://stackblitz.com/edit/angular-ivy-m4w2tk . But using the code above in my project generates a compiler error:

Type 'false | Type<any>' is not assignable to type 'Type<any>'

I need a clean way to remove this component.

https://stackblitz.com/edit/angular-ivy-m4w2tk

Thanks.

Option 1

You could also set the component ref to null: https://stackblitz.com/edit/angular-ivy-tcbdsh?file=src%2Fapp%2Fapp.component.ts

Template:

<ng-container *ngComponentOutlet="component"></ng-container>

Component:

public component = HelloWorld;

toggleHelloWorld(): void {
  if (!this.component) {
    this.component = HelloWorld;
  } else {
    this.component = null;
  }
}

Option 2

You can wrap your container in another element and use an *ngIf on it like here: https://stackblitz.com/edit/angular-ivy-ct8xmh?file=src%2Fapp%2Fapp.component.ts

<ng-container *ngIf="show">
    <ng-container *ngComponentOutlet="component"></ng-container>
</ng-container>

This looks very much like the code you tried but the component does indeed run the OnDestroy lifecycle hook.

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