angular - Mat-tab-group's [(selectedIndex)]=... binding is flaky
问题描述
I am using Angular and the MaterialTabs module.
I have a list of tabs in my component that I display using mat-tabs and ngFor, plus one more disabled tab with a plus button. When clicking the plus button, I would like to add a new tab and immediately focus on that tab. (Similarly to how browser tabs work.)
This is how it looks like:
I do this by two-way property-binding to the selectedIndex property of the mat-tab-group and setting it from my component inside the button click event handler.
You can see that the tabgroup's property and the property bound to it is equal, when it works.
However, I ran into a problem, where if I freshly load the page and click on the button first, the property binding somehow breaks:
Clicking once on any of the Tabs seems to fix the issue forever. The issue comes back when you reload the page.
From my understanding the following property binding would make sure that the values will always be equal and if one of them changes the other will follow:
[(selectedIndex)]="selectedIndexBinding"
So how can selectedIndex be 1, while selectedIndexBinding is 0?
How can I fix this issue?
Live example:
https://stackblitz.com/edit/angular-82vgrj
Code:
src/app/app.component.html
<mat-tab-group [(selectedIndex)]="selectedIndexBinding" #tabGroup>
<mat-tab *ngFor="let tab of tabs">
<ng-template mat-tab-label>
{{ tab }}
</ng-template>
</mat-tab>
<mat-tab disabled>
<ng-template mat-tab-label>
<button mat-icon-button (click)="addTab()">
+
</button>
</ng-template>
</mat-tab>
</mat-tab-group>
selectedIndex: {{ tabGroup.selectedIndex }}<br />
selectedIndexBinding: {{ selectedIndexBinding }}
src/app/app.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
public selectedIndexBinding = 0;
public tabs = [];
public addTab() {
this.tabs.push("Tab");
this.selectedIndexBinding = this.tabs.length - 1;
}
}
解决方案
您的问题来自您设置新索引的方式,因为无论如何button
a都很重要tab
。
您需要使用以下方法检索原件mat-tab-group
:
@ViewChild('tabGroup', {static: false}) tab: MatTabGroup;
并直接设置您想要的索引:
this.tab.selectedIndex = this.tabs.length - 1;
你可能会注意到我把它都放在了一个setTimeout
. 它用于Angular 生命周期钩子,setTimeout 触发一个新的 Angular 周期。
代码:
src/app/app.component.html
<mat-tab-group [(selectedIndex)]="selectedIndexBinding" #tabGroup>
<mat-tab *ngFor="let tab of tabs">
<ng-template mat-tab-label>
{{ tab }}
</ng-template>
</mat-tab>
<mat-tab disabled>
<ng-template mat-tab-label>
<button mat-icon-button (click)="addTab($event)">
+
</button>
</ng-template>
</mat-tab>
</mat-tab-group>
selectedIndex: {{ tabGroup.selectedIndex }}<br />
selectedIndexBinding: {{ selectedIndexBinding }}
src/app/app.component.ts
import { Component, ViewChild } from '@angular/core';
import { MatTabGroup } from '@angular/material';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
@ViewChild('tabGroup', {static: false}) tab: MatTabGroup;
public selectedIndexBinding = 0;
public tabs = [];
public addTab(e: Event) {
this.tabs.push("Tab");
e.preventDefault();
setTimeout(() => {
console.log(this.tabs, this.tab.selectedIndex);
this.tab.selectedIndex = this.tabs.length - 1;
});
}
}
推荐阅读
- python-3.x - 在应用程序中添加新的 tkinter 模块以及从它们调用条目的能力
- javascript - 如何在 angularjs 服务中使用 $scope
- python - Python 中的类:__str__ 方法和列表
- python - Pandas Dataframe:多维分箱
- python - TypeError:“int”对象在使用 random.choices 的二十一点游戏中不可下标
- java - spring 请求主体将名称分配给数组/列表
- azure - 使用 Azure API 管理进行直通但返回显示重定向的 html
- django - django没有清理以前的数据
- database - Kotlin:sqlite 数据库表未创建
- tensorflow - ML.NET 无法加载 TensorFlow 模型 h5