- 提供providers
- 创建Injector实例
- 创建ComponetFactory
- 使用ComponetFactory创建ComponentRef
//ComponentFactory的create方法 create(injector: Injector, projectableNodes?: any[][], rootSelectorOrNode?: string|any, ngModule?: NgModuleRef<any>): ComponentRef<C> //使用Injector的create创建injector实例 static create(providers: StaticProvider[], parent?: Injector): Injector
为了代码的复用,这里创建通用的loader类来完成组件的动态创建。其中,attch方法用于初始化ComponetFactory(参数为组件类型);to方法用于标识组件的父容器;provider方法用于初始化可注入的类;create方法用于创建组件并手动变更检测;remove方法用于移除组件。
import {
ComponentFactoryResolver,
ComponentFactory,
ComponentRef,
Type,
Injector,
Provider,
ElementRef
} from '@angular/core';
export class ComponentLoader<T>{
constructor(private _cfr: ComponentFactoryResolver,
private _injector: Injector) {
}
private _componentFactory: ComponentFactory<T>
attch(componentType: Type<T>): ComponentLoader<T> {
this._componentFactory = this._cfr.resolveComponentFactory<T>(componentType);
return this;
}
private _parent: Element
to(parent: string | ElementRef): ComponentLoader<T> {
if (parent instanceof ElementRef) {
this._parent = parent.nativeElement;
} else {
this._parent = document.querySelector(parent);
}
return this;
}
private _providers: Provider[] = [];
provider(provider: Provider) {
this._providers.push(provider);
}
create(opts: {}): ComponentRef<T> {
const injector = Injector.create(this._providers as any[], this._injector);
const componentRef = this._componentFactory.create(injector);
Object.assign(componentRef.instance, opts);
if (this._parent) {
this._parent.appendChild(componentRef.location.nativeElement);
}
componentRef.changeDetectorRef.markForCheck();
componentRef.changeDetectorRef.detectChanges();
return componentRef;
}
remove(ref:ComponentRef<T>){
if(this._parent){
this._parent.removeChild(ref.location.nativeElement)
}
ref=null;
}
}
同时,为了便于loader的创建,再创建LoaderFactory类,代码如下:
import {
ComponentFactoryResolver,
Injector,
Injectable,
ElementRef
} from '@angular/core';
import { ComponentLoader } from './component-loader.class';
@Injectable()
export class ComponentLoaderFactory {
constructor(private _injector: Injector,
private _cfr: ComponentFactoryResolver) {
}
create<T>(): ComponentLoader<T> {
return new ComponentLoader(this._cfr, this._injector);
}
}
message service
message service提供显示message的API,代码如下:
