動態添加一個component:
import {
ViewContainerRef,
Component,
ComponentFactoryResolver,
ViewChild
} from '@angular/core';
import {InstanceComponent} from ' ./ instance.component';
@Component{
selector:'my-app'
template:`
<div #insert>
insert Component
</div>
`
}
export class AppComponent{
@ViewChild('insert',{read:ViewContainerRef})insert;
constructor(
private _vcr:ViewContainerRef
private _cfr:ComponentFactoryResolver
){}
ngAfterViewInit(){
let factory=this._cfr.resolveComponentFactory(InstanceComponent); //先轉換成factoryComponent類型。
this._vcr.createComponent(factory); // 在本component末尾加入factory;
//或者this.insert.createComponent(factory); // 在#insert內部的末尾加入factory;
}
clear(){
this._cfr.clear() //清除加入的元素。
}
remove(){ //既然有加入component,那么也得寫一個刪除的方法。
let node=this.insert.nativeElement;
node.parentNode.removeChild(node);
}
}
angular中的NgModule中存在entryComponents屬性,一般是不需要配置的。因為被bootStrap直接及遞歸引導的component和router中定義的component,會被自動添加入entryComponent。
可是我們要加入的這個component,就沒有落腳之地,所以你需要自己在app.module中的entryComponents里加入這個component。
下面是一些API:
一,
@ViewChild:
@ViewChild('insert',{read:_params});
_params:默認值為ElementRef;另一個可選值為ViewContainer;
@ViewChildren:
在@ViewChild中填入component,難免該component不止被使用一次。所以在多次出現時,使用viewChildren;
@ContentChild:
首先你得分清content與view的差別。他們所對應的元素,view是在native element中定義,content是在host element中定義再映射入native中。
@ContentChild(component) ;獲得projection component;
@ContentChildren:
相對於ContentChild選擇多個。
使用進階:
@Directive({
selector:'div',
})export class myDirective{
constructor(
private el:ElementRef;
){}
}
@Component ({
template:`
<div id='div1'> one</div>
<div> two </div>
`
})export class AppComponent{
@ViewChildren(myDirective)_md;
ngAfterView(){
this._md.map(node=>{
console.log(node.el.nativeElement.nodeName);
});
this._md.changes.subscribe(val=>{.....});
}
}
@ViewChildren返回一個:QueryList。擁有map方法,但它不屬於Array。
myDirective將<div>綁定為一個Directive,並使其具有.el屬性。其中第一個div多帶一個id屬性。注意,不做injector或者attr,將返回一個空的{}。
this._md.changes可以監聽這些ViewChildren的變化,比如add,move,remove.
@ContentChildren。使用方法雷同。
二,動態 innerHTML。
ViewContainerRef.createEmbeddedView
@Component ({
template:`
<template #tp>
<h1> templateRef</h1>
</template>
`
})export class AppComponent{
@ViewChild('tp')tp;
constructor(private _vcr:ViewContainerRef){};
ngAfterViewInit(){
this._vcr.createEmbeddedView(tp);
}
}
@ViewChild('tp')得到的是一個templateRef;
通過這個方法,可以達成類似Jquery 中,$('<h1> templateRef</h1>').insertAfter('my-app')的效果。
三,私有注入。
ViewProviders:[];
angular中除了惰性模塊,一旦你使用providers注冊服務,那它會立即提升為全局。
所以在一些特殊情況需要私有服務時,我們使用ViewProviders代替providers,因為ViewProviders內的服務,只能被自身及ViewChildren使用。
------------這個排版不好用啊。有時間自己搞幾個class。。。- -!
