简体   繁体   中英

Dynamically add mat-tab to a wrapped mat-tab-group

My end goal is to create a reusable mat-tab-group component that adds some functionality to be able to close all tabs. I have found a technique for doing this here:

https://stackoverflow.com/a/53818913/811277

My next set was to wrap the functionality so it can be turned into a re-usable component. I have tried using the technique found here:

Angular Material Tabs not working with wrapper component

In the end I'm having trouble creating an empty MatTab component to insert at the beginning my list of MatTabs.

I've created a StackBlitz for this:

https://stackblitz.com/edit/angular9-material-baseline-nns7wc

  public ngAfterViewInit() {
     const matTabsFromQueryList = this._allTabs.map((tab) => tab.matTab);
     const list = new QueryList<MatTab>();
     // Create & Prepend a new MatTab here?
     list.reset([matTabsFromQueryList]);
     this._tabBodyWrapper._tabs = list;
  }

I was hoping to just create a MatTab component in the code above, but it isn't as simple as just saying new MatTab();

I solved this by taking a deeper look at the code that was wrapping mat-tab-group . It was reading the children via @ContentChildren and attaching them to the _allTabs property. Therefore, my solution was to provide a <mat-tab> in the template and just make sure it was the first item in the list/query that gets assigned to _allTabs . Here is the full source for my solution:

 import { Component, ContentChildren, QueryList, ViewChild, ViewContainerRef, ChangeDetectorRef, } from '@angular/core'; import { MatTab, MatTabGroup } from '@angular/material/tabs'; import { UiTabExtendedComponent } from '../ui-tab-extended/ui-tab-extended.component'; @Component({ selector: 'ui-tabs-extended', styleUrls: ['./ui-tabs-extended.component.scss'], template: ` <div class="footer-tabs-flex"> <div class="footer-tabs-flex-main"> <mat-tab-group #_tabBodyWrapper class="footer-tabs"> <mat-tab #_blankTab></mat-tab> <ng-content #outlet></ng-content> </mat-tab-group> </div> <div class="footer-tabs-flex-close"> <mat-icon mat-list-icon fontSet="fal" fontIcon="fa-times" (click)="_tabBodyWrapper.selectedIndex = 0" ></mat-icon> </div> </div> `, }) export class UiTabsExtendedComponent { @ViewChild(MatTabGroup) public _tabBodyWrapper: MatTabGroup; @ViewChild(MatTab) public _blankTab: MatTab; @ContentChildren(UiTabExtendedComponent) protected _allTabs: QueryList<UiTabExtendedComponent>; @ViewChild('outlet', { read: ViewContainerRef }) container; constructor(private cd: ChangeDetectorRef) {} public ngAfterViewInit() { const matTabsFromQueryList = this._allTabs.map((tab) => tab.matTab); matTabsFromQueryList.unshift(this._blankTab); const list = new QueryList<MatTab>(); list.reset([matTabsFromQueryList]); this._tabBodyWrapper._allTabs = list; this._tabBodyWrapper.ngAfterContentInit(); this.cd.detectChanges(); } }
 ::ng-deep.mat-tab-labels >.mat-tab-label:first-child { display: none; }.footer-tabs { width: 100%; }.footer-tabs-flex { display: flex; background-color: #dde1ec; }.footer-tabs-flex-main { flex: 1; }.footer-tabs-flex-close { flex-shrink: 0; margin-left: 16px; margin-top: 16px; mat-icon { cursor: pointer; } }

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