如何使用 Angular Materials 选项卡制作自定义选项卡?

问题描述 投票:0回答:3

我想使用 Angular Material 库并通过一些自定义设计构建我自己的库。但在拆分材料成分时面临一些问题。我认为问题出在 Shadow DOM 上。这是我想要实现的代码。

代码

自定义选项卡组.html-父级

<div class="custom-tabs">
  <mat-tab-group disableRipple>
    <ng-content></ng-content>
  </mat-tab-group>
</div>

custom-tabs.html-child

<custom-tabs-group [tabContent]="tabContent">
  <mat-tab *ngFor="let tab of tabContent" label="{{tab.title}}">{{tab.content}} </mat-tab>
</custom-tabs-group>

有可能吗?请告诉我

javascript angular angular-material angular-cli
3个回答
1
投票

您共享的代码向后获取了 ng-content 用法...

<custom-tabs-group>
将位于父级别,
<ng-content>
将位于子级别。

我尝试了两种方法:

  • 策略#1:将内容传递给
    <mat-tab>
    内的自定义子项...这有效
  • 策略#2:将内容传递给自定义子项,其中
    <mat-tab>
    在子项内部...这不起作用

您可以在此处查看演示


1
投票

实际上我通过一些技巧解决了这个问题,我不知道这是否是一个好的方法

自定义选项卡.component.html

<div class="custom-tabs">
  <mat-tab-group disableRipple>
    <mat-tab *ngFor="let tab of tabsContentList" label="{{tab.label}}">
      <div [innerHTML]="tab.htmlContent"></div>
    </mat-tab>
  </mat-tab-group>
</div>

自定义选项卡组件.ts

import { DomSanitizer } from '@angular/platform-browser';
import { Component, OnInit, ViewEncapsulation, AfterContentInit, ContentChildren, Input, ViewChild, ElementRef, QueryList } from '@angular/core';


@Component({
  selector: 'il-tabs-content',
  template: `
      <div #content>
         <ng-content></ng-content>
       </div>
       `
  ,
})
export class TabsContentComponent implements OnInit {
  @Input() label: String;
  @ViewChild('content') set content(content: ElementRef) {
    console.log("block three", content)
    this.htmlContent = content;
    if (this.htmlContent) {
      this.htmlContent = this.htmlContent.nativeElement.innerHTML;
    }
  }

  htmlContent: any;
  constructor() { }
  ngOnInit() {
  }

}

@Component({
  selector: 'il-tabs-group',
  templateUrl: './tabs.component.html',
  styleUrls: ['./tabs.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class TabsGroupComponent implements OnInit, AfterContentInit {
  @ContentChildren(TabsContentComponent) tabsContentList: QueryList<TabsContentComponent>;

  constructor(public sanitizer: DomSanitizer) { }

  ngOnInit() {

  }
  ngAfterContentInit() {
    this.tabsContentList.forEach((tabInstance) => {
      var sanEle = this.sanitizer.bypassSecurityTrustHtml(tabInstance.htmlContent)
      tabInstance.htmlContent = sanEle;
      return tabInstance
    })
  }
}

用法

  <il-tabs-group>
    <il-tabs-content label="hello-1">
      <h1>hello-1 content</h1>
    </il-tabs-content>
    <il-tabs-content label="hello-2">
      <h1>hello-2 content</h1>
    </il-tabs-content>
    <il-tabs-content label="hello-3">
      <h1>hello-3 content</h1>
      <h2>extra content</h2>
    </il-tabs-content>
  </il-tabs-group>

我定义了两个组件“il-tabs-content”和“li-tabs-group”。有了这个,我现在可以使用我自己的自定义选项卡构建在带有动态选项卡的角度材料选项卡上。欢迎有更好方法的朋友分享自己的想法。谢谢


0
投票

首先感谢您的代码为我指出了解决方案:)我认为我已经升级了它以满足您的需求。

选项卡内容组件

import { Component, Input, TemplateRef, ViewChild } from '@angular/core';

@Component({
    selector: 'il-tabs-content',
    templateUrl: './tab-content.component.html',
})
export class TabContentComponent {
    @Input() icon = '';
    @Input() label = '';
    @ViewChild('content') content!: TemplateRef<string>;
}
<ng-template #content>
    <ng-content></ng-content>
</ng-template>

在 TabsGroupComponent 中:

import { ChangeDetectionStrategy, Component, ContentChildren, Input, QueryList } from '@angular/core';
import { TabContentComponent } from '@app/shared/components/tab-content/tab-content.component';

@Component({
    selector: 'il-tabs-group',
    templateUrl: './tabs-group.component.html',
    styleUrls: ['./tabs-group.component.scss'],
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TabsGroupComponent {
    @Input() disableRipple = true;
    @Input() animationDuration = '0ms';
    @ContentChildren(TabContentComponent, {
        descendants: true,
    }) tabsContentList!: QueryList<TabContentComponent>;
}
<div class="tabs-group">
    <mat-tab-group [animationDuration]="animationDuration"
                   [disableRipple]="disableRipple">
        <mat-tab *ngFor="let tab of tabsContentList">
                <ng-template mat-tab-label>
                    <i class="icon {{tab.icon}}"></i>
                    <div class="label" translate>{{ tab.label }}</div>
                </ng-template>
                <ng-container [ngTemplateOutlet]="tab.content"></ng-container>
        </mat-tab>
    </mat-tab-group>
</div>

我必须能够添加自定义图标,因此代码会更复杂,但最终,无需 DOM 清理即可正常工作:)

干杯

© www.soinside.com 2019 - 2024. All rights reserved.