我一直在试图制作一个标签视图,并认为内容投影可能是一个好方法。我从这个article中了解到它。我认为只要输入一个给定的组件数组就可以使其动态化,并且它们将显示为选定选项卡的页面。当动态创建子组件时,父组件的Angular 2- ContentChidren是未定义的
这是我在做这样的尝试:
@Component({
selector: 'my-app',
template:`
<h1>Experiments</h1>
<button class="add-button" (click)="add()">Add</button>`
})
export class App {
components:Array<any> = [PrepSetupTab,FinalizeTab]
constructor(private cdr: ChangeDetectorRef,
private compFR: ComponentFactoryResolver,
private viewContainer: ViewContainerRef){}
add():void{
var transTabRefs: Array<any>= []
this.components.forEach(tabComponent=>{
let compFactory = this.compFR.resolveComponentFactory(tabComponent);
let compRef = this.viewContainer.createComponent(compFactory);
let tabFactory = this.compFR.resolveComponentFactory(Tab);
let transcludedTabRef = this.viewContainer.createComponent(tabFactory,this.viewContainer.length - 1, undefined, [[compRef.location.nativeElement]]);
transTabRefs.push(transcludedTabRef.location.nativeElement);
})
let tabsFactory = this.compFR.resolveComponentFactory(Tabs); // notice this is the tabs not tab
this.viewContainer.createComponent(tabsFactory,0,undefined,[transTabRefs]);
}
}
侧面说明,添加()作为按钮的点击处理程序不打算等功能,以避免这个错误:"EXCEPTION: Expression has changed after it was checked"
。如果我把它放在任何生命周期钩子中,我会得到这个错误。虽然这对于稍后处理是一个挑战。
所以基本上我创建了数组中的每个组件,然后我将它们粘贴为每个创建的Tab组件的ng内容。然后将每个Tab组件粘贴到ng内容中以供制表符组件使用。
问题是Tabs组件未找到动态创建的Tab儿童的contentChildren。以下是未定义内容子项的Tabs组件的代码。
@Component({
selector: 'tabs',
template:`
<ul class="nav nav-tabs">
<li *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">
<a>{{tab.title}}</a>
</li>
</ul>
<ng-content></ng-content>
`
})
export class Tabs implements AfterContentInit {
@ContentChildren(Tab) tabs: QueryList<Tab>;
// contentChildren are set
ngAfterContentInit() {
// 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: Tab){
// deactivate all tabs
this.tabs.toArray().forEach(tab => tab.active = false);
// activate the tab the user has clicked on.
tab.active = true;
}
}
这似乎是很清楚,我认为该卡组件,在不同的时间产生了以后,当我需要访问它们从标签成分含量的孩子。我也尝试使用ChangeDetectionRef.changeDetect(),但这没有帮助。
也许通过内容投影完成这一切并不是最简单的方式或最好的,所以我愿意提供建议。这是plunk,谢谢!
'@ ContentChildren'不会与动态创建组件工作。这是由设计 – yurzui
http://plnkr.co/edit/t1GnzDDR2s5g8PSDojXv?p=preview – yurzui
哇,InitContent我以前没有看到过!想想看,你可能会认识到这些代码中的一些,因为我认为我从之前的plunk中获得了它:)。 –