我有一个制表组件,在此定义 https://stackblitz.com/edit/angular-tabs-example
我正在尝试将my-tabs中的ng-content放到外部ng-template中,有什么办法吗?我可以将ng-content分配给TemplateRef或ViewContainerRef。
答案 0 :(得分:0)
是的,您可以使用@ContentChild
角形表单,这将帮助您将内容从父组件传递给子组件-我将稍微更改代码
tabs.component.ts
@Component({
selector: 'my-tabs',
template: `
<ul class="nav nav-tabs">
<li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
<a href="#">{{tab.title}}</a>
</li>
</ul>
<ng-template [ngTemplateOutlet]="parentList"></ng-template>
`,
styles: [
`
.tab-close {
color: gray;
text-align: right;
cursor: pointer;
}
`
]
})
export class TabsComponent implements AfterContentInit {
@ContentChild('list') parentList: TemplateRef<any>;
}
app.component.ts
@Component({
selector: 'my-app',
template: `
<my-tabs>
<my-tab [tabTitle]="'Tab 1'">
Tab 1 content
</my-tab>
<ng-template #list>
<my-tab tabTitle="Tab 2">
Tab 2 content
</my-tab>
</ng-template>
</my-tabs>
`
})
export class AppComponent {
}
父组件中的<ng-template #list>
会将其内容在模板中传递给子组件-而子组件将读取内容并将其放入<ng-template [ngTemplateOutlet]="parentList"></ng-template>
通过这种方法,您可以将尽可能多的内容从父母传递给孩子-希望这对您有帮助
谢谢-祝您编程愉快! -检查此链接以进一步阐明https://angular.io/api/core/ContentChild
答案 1 :(得分:0)
我使用下面的代码解决了这个问题,我正在使用Output EventEmitter获取ng-content并将其放在父模板中。欢迎任何建议,我需要帮助来改进它。
parent.component.html
<sb-tabs contentMode="external" (templateAfterInit)="tabContentSet($event)">
<sb-tab *ngIf="jobId" tabTitle="Invoices">
Hello
</sb-tab>
</sb-tabs>
侧边栏
显示内容
parent.component.ts
@ViewChild("tabContent")
tabContent: TemplateRef<any>;
tabContentSet(event) {
this.tabContent = event.template;
}
tabs.component.ts
import {
Component, AfterContentInit, ContentChildren, QueryList
, Input, Output, ViewChild, EventEmitter
} from '@angular/core';
import { TabComponent } from './tab.component'
enum TabContentMode { internal = 'internal', external = 'external' }
@Component({
selector: 'sb-tabs',
template: `
<ul class="nav nav-tabs {{cssClasses.tabsBar}}">
<li class="nav-item" *ngFor="let tab of tabs" (click)="selectTab(tab)">
<a class="nav-link" [class.active]="tab.active">{{tab.title}}</a>
</li>
</ul>
<ng-container *ngIf="contentMode == 'internal'" [ngTemplateOutlet]="tabsContent">
</ng-container>
<ng-template #tabsContent>
<ng-content></ng-content>
</ng-template>
`
})
export class TabsComponent implements AfterContentInit {
@Input() cssClasses: any = {
tabsBar: 'nav nav-tabs'
};
@ContentChildren(TabComponent) tabs: QueryList<TabComponent>;
@ViewChild("tabsContent")
private externalTemplate: any;
@Input() contentMode: TabContentMode = TabContentMode.internal;
@Output("templateAfterInit")
templateAfterInit = new EventEmitter();
constructor() { }
ngAfterContentInit(): void {
this.templateAfterInit.emit({ template: this.externalTemplate });
// get all active tabs
let activeTabs = this.tabs.filter((tab) => tab.active);
// if there is no active tab set, activate the first
if (activeTabs.length === 0) {
this.selectTab(this.tabs.first);
}
}
selectTab(tab: TabComponent) {
// deactivate all tabs
this.tabs.toArray().forEach(tab => tab.active = false);
// activate the tab the user has clicked on.
tab.active = true;
}
}
tab.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { fadeInOut } from '@shared/common/animations';
@Component({
selector: 'sb-tab',
animations: [fadeInOut],
template: `
<div [@fadeInOut] *ngIf="active" class="pane">
<ng-content></ng-content>
</div>
`
})
export class TabComponent implements OnInit {
@Input('tabTitle') title: string;
@Input() active = false;
constructor() { }
ngOnInit() {
}
}