Reputation: 376
I am using Angular Material Tabs to navigate different sections of a document. I've defined each tab in a TabItem class which looks like this:
class TabItem {
constructor(
public component: Type<any>,
public data: TabData,
public active: boolean
) {}
}
In the view, I loop through each TabItem and use *ngComponentOutlet to render the component of each 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>
Everything works well... except I need access to the current TabItem in each of the resolved components to access its id, label, etc. The reason I am having trouble is because the examples online only show how to use ngComponentOutlet as a dynamic component. My components arent dynamic though... they are fixed, but created on the fly.
I dont know how I can use an injector since I am in a for loop... unless I create an injector for each individual item. I also dont want to subscribe to a service in every component... thats just ridiculous.
Here is a stackblitz of what I am trying to accomplish.
Upvotes: 1
Views: 1688
Reputation: 214255
You can create a directive that will port desired data to your components:
data-provider.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">
Now your dynamically generated component can read data from that directive:
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)
}
}
Upvotes: 2