首页 > 解决方案 > 使用 ngComponentOutlet 的 Angular 材质选项卡

问题描述

我正在使用Angular Material 选项卡来导航文档的不同部分。我在 TabItem 类中定义了每个选项卡,如下所示:

class TabItem {
     constructor(
         public component: Type<any>, 
         public data: TabData,
         public active: boolean
     ) {}
}

在视图中,我循环遍历每个 TabItem 并使用 *ngComponentOutlet 来渲染每个 TabItem 的组件。

<mat-tab-group>
    <ng-container *ngFor="let tab of tabs">
        <mat-tab>
             <ng-template mat-tab-label>
                   <div class="mat-label-text" (click)="setActiveTab(tab)">{{ tab.data.label }}</div>
             </ng-template>

             <ng-container *ngComponentOutlet="tab.component"></ng-container>
        </mat-tab>
    </ng-container>
</mat-tab-group>

一切正常...除了我需要访问每个已解析组件中的当前 TabItem 以访问其 id、标签等。我遇到问题的原因是因为在线示例仅显示如何将 ngComponentOutlet 用作动态组件. 我的组件虽然不是动态的......它们是固定的,但是是动态创建的。

我不知道如何使用注射器,因为我处于 for 循环中......除非我为每个单独的项目创建一个注射器。我也不想订阅每个组件中的服务……这太荒谬了。

这是我想要完成的事情的堆栈闪电战。

标签: javascriptangulartypescriptangular-material

解决方案


您可以创建一个指令,将所需的数据移植到您的组件:

数据提供者.directive.ts

import { Directive, Input } from "@angular/core";

@Directive({
  selector: '[dataProvider]'
})
export class DataProviderDirective {
  @Input('dataProvider') data: any;
}

tabs.html

<ng-container *ngFor="let tab of tabs">
  <mat-tab [dataProvider]="tab">

现在您的动态生成的组件可以从该指令中读取数据:

tab-one.component.ts

import { Component, OnInit } from '@angular/core';
import { DataProviderDirective } from './data-provider.directive';

@Component({
  selector: 'app-tab-one',
  template: `
    <p>I am tab one!</p>
    <p>How can I access my respective TabItem?</p>
    <pre>{{ dataProvider.data | json }}</pre> 
  `,
})
export class TabOneComponent implements OnInit {

  constructor(public dataProvider: DataProviderDirective) { }

  ngOnInit() {
    console.log(this.dataProvider.data)
  }
}

分叉的 Stackblitz


推荐阅读