Angular2 - DynamicComponentLoader 用法

DynamicComponentLoader 主要的能力就是动态加载组件:

文档给出了3个用法

  • 1
constructor(dcl: DynamicComponentLoader, injector: Injector) {
dcl.loadAsRoot(ChildComponent, '#child', injector);
}

loadAsRoot - (子组件名字,用于定位插入的节点位置,injector)

效果是 子组件的Template 插入到了父组件中 id=”child “ 标签里面

<child id="child">a</child>
  • 2
constructor(dcl: DynamicComponentLoader, elementRef: ElementRef) {
dcl.loadIntoLocation(ChildComponent, elementRef, 'child');
}

loadIntoLocation (子组件,elementRef, 锚点名字 )

效果是 找到父组件里的锚点位置标签
把 子组件 标签插入 锚点标签下面(不是里面)

<child></child>
<child-component>a</child-component>
  • 3

     

    loadNextToLocation(子组件 ,子组件,elementRef )

    直接发子组件插入到父组件下面 (不是里面)

    <parent-component>Parent (<child id="child"></child>)(<child></child>)</parent-component>
    <child-component><div>good</div></child-component>

延伸下:

 @Injectable()
export class DynamicComponentLoader_ extends DynamicComponentLoader {
constructor(private _compiler: Compiler, private _viewManager: AppViewManager) { super(); }

loadAsRoot(type: Type, overrideSelector: string, injector: Injector, onDispose?: () => void,
projectableNodes?: any[][]): Promise<ComponentRef> {
return this._compiler.compileInHost(type).then(hostProtoViewRef => {
var hostViewRef = this._viewManager.createRootHostView(hostProtoViewRef, overrideSelector,
injector, projectableNodes);
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);

var dispose = () => {
if (isPresent(onDispose)) {
onDispose();
}
this._viewManager.destroyRootHostView(hostViewRef);
};
return new ComponentRef_(newLocation, component, type, injector, dispose);
});
}

loadIntoLocation(type: Type, hostLocation: ElementRef, anchorName: string,
providers: ResolvedProvider[] = null,
projectableNodes: any[][] = null): Promise<ComponentRef> {
return this.loadNextToLocation(
type, this._viewManager.getNamedElementInComponentView(hostLocation, anchorName), providers,
projectableNodes);
}

loadNextToLocation(type: Type, location: ElementRef, providers: ResolvedProvider[] = null,
projectableNodes: any[][] = null): Promise<ComponentRef> {
return this._compiler.compileInHost(type).then(hostProtoViewRef => {
var viewContainer = this._viewManager.getViewContainer(location);
var hostViewRef = viewContainer.createHostView(hostProtoViewRef, viewContainer.length,
providers, projectableNodes);
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);

var dispose = () => {
var index = viewContainer.indexOf(hostViewRef);
if (!hostViewRef.destroyed && index !== -1) {
viewContainer.remove(index);
}
};
return new ComponentRef_(newLocation, component, type, null, dispose);
});
}
}

这里有几种View,AppViewManager 是用来操作view
View container 可以包含两种view

  • hostViewRef —
  • Embedded Views — TemplateRef_ 请查看*ngIf 源码解读
 loadAsRoot(type: Type, overrideSelector: string, injector: Injector, onDispose?: () => void,
projectableNodes?: any[][]): Promise<ComponentRef> {
//把component 转成 hostProtoViewRef
return this._compiler.compileInHost(type).then(hostProtoViewRef => {
//根据overrideSelector 找到那个tag, createRootHostView
var hostViewRef = this._viewManager.createRootHostView(hostProtoViewRef, overrideSelector,
injector, projectableNodes);
//根据hostViewRef 拿到ComponentRef_ (这里是child-component)
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);

var dispose = () => {
if (isPresent(onDispose)) {
onDispose();
}
this._viewManager.destroyRootHostView(hostViewRef);
};
return new ComponentRef_(newLocation, component, type, injector, dispose);
});
}
return this._compiler.compileInHost(type).then(hostProtoViewRef => {
//location 传进来是elementRef, viewContainer 是父组件
var viewContainer = this._viewManager.getViewContainer(location);
//找到viewContainer,子组件的view - hostProtoViewRef放进去
var hostViewRef = viewContainer.createHostView(hostProtoViewRef, viewContainer.length,
providers, projectableNodes);
var newLocation = this._viewManager.getHostElement(hostViewRef);
var component = this._viewManager.getComponent(newLocation);

var dispose = () => {
var index = viewContainer.indexOf(hostViewRef);
if (!hostViewRef.destroyed && index !== -1) {
viewContainer.remove(index);
}
};
return new ComponentRef_(newLocation, component, type, null, dispose);
});

https://github.com/dreambo8563/node_angular2/blob/ng-pages/app/components/CompLoaderSample.ts