从数组构建 mat-tab-group 时关闭 mat-tab 后组件不会被销毁
Components are not being destroyed after closing a mat-tab when building a mat-tab-group from an array
我有一个数据集,它有一个面板数组,其中包含有关应该加载到 mat-tab-group 中的组件的信息。可以关闭 mat-tab-group 中的选项卡。为此,我更改了用于构建选项卡组的数据结构。因此,当我们有一个包含 4 个面板的数组(在选项卡组中呈现 4 个选项卡)并且我们删除一个面板时,该数组将只有 3 个值并且只呈现三个选项卡。
问题是已删除选项卡中的组件实际上会保持活动状态。我通过在我的组件的构造函数中添加一个间隔来测试它。组件没了,本以为真的没了,但是interval中的console.log会一直记录。
这是最小复制的堆栈闪电战:https://stackblitz.com/edit/angular-wfkpqq
我做了一些 Google 搜索并检查了文档,但我找不到任何关于关闭 mat-tabs 的信息。有一个人告诉某人这应该由用户实施,但他们并没有真正为您提供正确执行此操作的工具。
如何确保我的孤立组件被销毁?
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>
[编辑]
问题是别的。我分离了一个动态插入的组件,以便我可以移动组件。我在关闭组件时也这样做了,所以面板被分离了,所以 OnDestroy 永远不会被调用。我会接受唯一的答案,因为它引导我犯了错误。
我想我知道你的问题是什么。您的组件正在被销毁,问题是您没有关闭间隔。我玩过你的 stackblitz,如果你添加一个 ngOnDestroy(并实现 OnDestroy)并关闭间隔,你会看到一切都按预期工作
改变你的 annoying.component.ts
:
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
@Component({
selector: 'app-annoying',
templateUrl: './annoying.component.html',
styleUrls: ['./annoying.component.css']
})
export class AnnoyingComponent implements OnDestroy {
@Input() public name: string;
_interval:any;
constructor() {
this._interval = setInterval(() => {
console.log(this.name + ' still lives');
}, 1000);
}
ngOnDestroy(){
clearInterval(this._interval);
console.log(this.name + "is being destroyed");
}
}
您将看到日志 "is being destroyed"
显示,而其他日志在您关闭选项卡时停止。
问题在于缺少
clearInterval(this._interval);
看看这个答案:
我有一个数据集,它有一个面板数组,其中包含有关应该加载到 mat-tab-group 中的组件的信息。可以关闭 mat-tab-group 中的选项卡。为此,我更改了用于构建选项卡组的数据结构。因此,当我们有一个包含 4 个面板的数组(在选项卡组中呈现 4 个选项卡)并且我们删除一个面板时,该数组将只有 3 个值并且只呈现三个选项卡。
问题是已删除选项卡中的组件实际上会保持活动状态。我通过在我的组件的构造函数中添加一个间隔来测试它。组件没了,本以为真的没了,但是interval中的console.log会一直记录。
这是最小复制的堆栈闪电战:https://stackblitz.com/edit/angular-wfkpqq
我做了一些 Google 搜索并检查了文档,但我找不到任何关于关闭 mat-tabs 的信息。有一个人告诉某人这应该由用户实施,但他们并没有真正为您提供正确执行此操作的工具。
如何确保我的孤立组件被销毁?
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>
[编辑] 问题是别的。我分离了一个动态插入的组件,以便我可以移动组件。我在关闭组件时也这样做了,所以面板被分离了,所以 OnDestroy 永远不会被调用。我会接受唯一的答案,因为它引导我犯了错误。
我想我知道你的问题是什么。您的组件正在被销毁,问题是您没有关闭间隔。我玩过你的 stackblitz,如果你添加一个 ngOnDestroy(并实现 OnDestroy)并关闭间隔,你会看到一切都按预期工作
改变你的 annoying.component.ts
:
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
@Component({
selector: 'app-annoying',
templateUrl: './annoying.component.html',
styleUrls: ['./annoying.component.css']
})
export class AnnoyingComponent implements OnDestroy {
@Input() public name: string;
_interval:any;
constructor() {
this._interval = setInterval(() => {
console.log(this.name + ' still lives');
}, 1000);
}
ngOnDestroy(){
clearInterval(this._interval);
console.log(this.name + "is being destroyed");
}
}
您将看到日志 "is being destroyed"
显示,而其他日志在您关闭选项卡时停止。
问题在于缺少
clearInterval(this._interval);
看看这个答案: