動態添加一個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。。。- -!