I have a dataset which has an array of panels containing information about the component that should be loaded in a mat-tab-group. The tabs in the mat-tab-group can be closed. For that, I change the data structure that we use to build the tab-group. So when we have an array of 4 panels (that render 4 tabs in the tab-group) and we remove a panel, the array will only have 3 values and only three tabs are rendered.
The problem is that the components within the removed tab will actually stay alive. I tested this by adding an interval in the constructor of my component. When the component is gone, I expected it to really be gone, but the console.log in the interval will keep on logging.
Here's a stackblitz of the minimal reproduction: https://stackblitz.com/edit/angular-wfkpqq
I did some Google searches and checked the docs but I can't find anything about closing mat-tabs. There was one dude telling someone that this should be implemented by the user, but they don't really give you the tools to do this proper.
How can I make sure my orphaned components are destroyed?
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-dock',
templateUrl: './dock.component.html',
styleUrls: ['./dock.component.css']
})
export class DockComponent {
public dock: any;
constructor() {
this.dock = {
panels: [
{
name: 'panel1'
},
{
name: 'panel2'
},
{
name: 'panel3'
},
{
name: 'panel4'
}
]
}
}
public onClose(panel): void {
var index = this.dock.panels.indexOf(panel);
if (index > -1) {
this.dock.panels.splice(index, 1);
}
}
}
<mat-tab-group #tabs>
<ng-container *ngFor="let panel of dock.panels">
<mat-tab>
<ng-template mat-tab-label>
<div>
<span class="tab-title">{{panel.name}}</span>
<span style="flex: 1 1 auto;"></span>
<div class="tab-options">
<button mat-icon-button (click)="onClose(panel)">
<mat-icon>close</mat-icon>
</button>
</div>
</div>
</ng-template>
<!-- ng-template with matTabContent makes the tabs lazy load -->
<ng-template matTabContent>
<app-annoying [name]="panel.name"></app-annoying>
</ng-template>
</mat-tab>
</ng-container>
</mat-tab-group>
[edit] The problem was something else. I detached a dynamically inserted component so I could move components. I also did that when closing a component, so the panel was detached, so the OnDestroy would never be called. I will accept the only answer as it guided me to my mistake.
I think I know what your problem is. Your components are being destroyed, the problem is that you are not closing the interval. I played arround with your stackblitz and if you add a ngOnDestroy (and implement OnDestroy) and you close the interval, you will see that everything works as expected
change your
annoying.component.ts
:and you will see that the log
"is being destroyed"
shows and the other logs stop when you close the tab.The problems was with the lack of
Take a look at this answer:
https://stackoverflow.com/a/42395773/7041393