【问题标题】:Multiline mat tab group多行垫选项卡组
【发布时间】:2021-03-11 15:28:43
【问题描述】:

所以,我有一个垫子标签组,用户可以在其中动态添加标签。

<mat-tab-group class="main-tab-group mt-2" [selectedIndex]="selectedTab" (selectedTabChange)="tabChanged($event)">
    <mat-tab *ngFor="let tab of tabs; let tabIndex = index">
        <ng-template mat-tab-label>{{ tab.title }}
            <i class="material-icons" (click)="removeTab(tabIndex)">close</i>
        </ng-template>
        <div>
            <app-tab-content [tab]="tab"></app-tab-content>
        </div>
    </mat-tab>
    <mat-tab disabled>
        <ng-template mat-tab-label>
            <button mat-stroked-button (click)="addNewTab()">Add new tab</button>
        </ng-template>
    </mat-tab>
</mat-tab-group>

代码运行良好,但我需要知道是否有办法在发生这种情况时将新选项卡放在第二行:

【问题讨论】:

    标签: angular angular-material


    【解决方案1】:

    使用 TotallyNewb 解决方案存在一个问题,即 inkBar 不会垂直跟随选定的选项卡,在某些情况下也不会水平跟随(例如,如果调整了内容的大小 - 而不是窗口)。

    我的方法类似,但有一些改进:

    用法

    <mat-tab-group matMultilineTab>...</mat-tab-group>
    

    实施

    1.全局定义新样式

    • 我可以使用组件样式,但这会有其他缺点。

    • 我没有使用 disablePagination,只是因为我的版本是 8.2.3 因此 我正在隐藏控件。

        .mat-tab-group.mat-tab-multiline {
          .mat-tab-header:first-child {
            .mat-tab-header-pagination {
              display: none;
            }
      
            .mat-tab-labels {
              flex-wrap: wrap;
            }
          }
        }
      

    2。定义指令

    @Directive({
      selector: '[matMultilineTab]',
    })
    export class MatMultilineTabDirective implements OnInit, OnDestroy {
      @HostBinding('class.mat-tab-multiline') class = true;
    
      private readonly onDestroy = new Subject();
      private readonly resizeObserver: ResizeObserver;
      private resizeTimeout: number;
    
      constructor(
        private elementRef: ElementRef,
        private matTabGroup: MatTabGroup
      ) {
        this.matTabGroup.selectedTabChange.pipe(
          takeUntil(this.onDestroy)
        ).subscribe(() => this.updateInkBarPosition());
    
        this.resizeObserver = new ResizeObserver(() => {
          if (this.resizeTimeout)
            clearTimeout(this.resizeTimeout);
          this.resizeTimeout = setTimeout(() => this.updateInkBarPosition(), 100);
        });
      }
    
      ngOnInit() {
        this.resizeObserver.observe(
          this.elementRef.nativeElement.querySelector('.mat-tab-header:first-child')
        );
      }
    
      ngOnDestroy() {
        this.resizeObserver && this.resizeObserver.disconnect();
    
        this.onDestroy.next();
        this.onDestroy.complete();
      }
    
      private updateInkBarPosition() {
        const headerElement: HTMLElement = this.elementRef.nativeElement.querySelector(
          '.mat-tab-header:first-child'
        );
        const activeTabElement: HTMLElement = headerElement.querySelector(
          '.mat-tab-label-active'
        );
        const inkBarElement: HTMLElement = headerElement.querySelector('.mat-ink-bar');
        const listElement: HTMLElement = headerElement.querySelector('.mat-tab-list');
        const bottom = listElement.offsetHeight - 
          (activeTabElement.offsetTop + activeTabElement.offsetHeight);
    
        inkBarElement.style.bottom = bottom + 'px';
        inkBarElement.style.left = activeTabElement.offsetLeft + 'px';
      }
    }
    

    【讨论】:

      【解决方案2】:

      这在一定程度上违反了材料设计指南,但应该可以实现。

      1. mat-tab-group 上的disablePagination 设置为true - 如果选项卡标签溢出可用空间,这将删除侧面的“导航”按钮。
      2. 向您的 mat-tab-group 添加一个自定义类,以便您可以更轻松地应用样式(即不使用 ::ng-deep 和 !important)。
      3. flex-wrap: wrap 添加到.your-class .mat-table-labels 选择器。这将使标签标签换行而不是溢出。请注意,遗憾的是,这必须是您的样式。(s)css。

      工作 stackblitz 示例供参考: https://stackblitz.com/edit/angular-8ssy8d

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 2011-01-18
        相关资源
        最近更新 更多