私はタブビューを作成しようとしていましたが、コンテンツの投影が良いアプローチかもしれません。articleから学びました。私は、コンポーネントの配列を入力するだけで動的にすることができ、選択したタブのページとして表示されると考えました。 "EXCEPTION: Expression has changed after it was checked"
:ボタンのクリックハンドラは、このバグを避けるために他の機能を意図していないと()を追加し、子コンポーネントを動的に作成するときに、親コンポーネントの角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]);
}
}
サイドノート:ここで
は、これを行うに私の試みです。どんなライフサイクルフックに入れてもこのバグが出ます。それは後で対処するのが難しいですが。
基本的に私は配列内の各コンポーネントを作成していますが、作成したタブコンポーネントごとにそれらをng-contentとして貼り付けています。次に、各Tabコンポーネントを取得し、タブコンポーネントのng-contentに貼り付けます。
タブコンポーネントは、動的に作成されたタブの子のcontentChildrenを見つけられません。コンテンツの子が未定義のタブコンポーネントのコードは次のとおりです。
@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、ありがとう!
'でそれを観察することができ、あなたのタブ
を初期化する可能性があります。これは設計によるものです – yurzui
http://plnkr.co/edit/t1GnzDDR2s5g8PSDojXv?p=preview – yurzui
Wow、InitContent私は前にそれを見たことがありません!そして、私は以前の大急ぎからそれを得たと思うので、あなたはこのコードのいくつかを認識するかもしれないと思うようになります:)。 –