2016-12-14 116 views
1

我想知道创建动态组件的最佳方式(性能)是什么。 我尝试了两个,但我无法确定我应该使用哪一个。Angular2动态组件的最佳方式

在我component.html容器中的NG-开关

@Component({ 
    selector: 'app-component-container', 
    template: `<div [ngSwitch]="typeComponent"> 
       <app-component-one *ngSwitchCase="1" [value]="someValue"></app-component-one> 
       <app-component-two *ngSwitchCase="2" [value]="someValue"></app-component-two> 
       <app-component-three *ngSwitchCase="3" [value]="someValue"></app-component-three> 
       </div>` 
}) 
export class ContainerComponent implements OnInit { 
    private typeComponent: number; 
    private someValue: string; 

    constructor() { 
    this.typeComponent = 2; 
    this.someValue = "Hello"; 

    } 

    ngOnInit() { 

    } 
} 

,或者在我的component.ts容器的组分助洗剂

@Component({ 
    selector: 'app-component-container', 
    template: '<div #container></div>' 
}) 
export class ContainerComponent implements OnInit { 
    @ViewChild('container', {read: ViewContainerRef}) container: ViewContainerRef; 

    private typeComponent: number; 

    private someValue: string; 

    constructor(private _resolver: ComponentFactoryResolver) { 
    this.typeComponent = 2; 
    this.someValue = "Hello"; 
    } 

    ngOnInit() { 
    let childComponent: ComponentRef<any> = null; 
    switch (this.typeComponent) { 
     case 1: 
     childComponent = this.container.createComponent<ChildComponentOne>(this._resolver.resolveComponentFactory(ChildComponentOne)); 
     break; 
     case 2: 
     childComponent = this.container.createComponent<ChildComponentTwo>(this._resolver.resolveComponentFactory(ChildComponentTwo)); 
     break; 
     case 3: 
     childComponent = this.container.createComponent<ChildComponentThree>(this._resolver.resolveComponentFactory(ChildComponentThree)); 
     break; 
    } 

    if (childComponent != null) { 
     childComponent.instance.value = this.someValue; 
    } 
    } 
} 

这是简单的为例,在我的应用程序有动态组件的巨大重塑。

非常感谢您的回答。

+0

在我的第二为例,很酷的事情是,我可以有我的childComponent一个例子,我可以很容易地操纵实例并调用方法。在我看来,这是更多的OO方式。 – Soulm8

回答

1

虽然这两种方式都是可行的,但为了DRYness,可读性和将来的维护,我可能会采取第二种方式 - 即通过API创建一个动态组件,并将其作为容器的子项插入...在基础

ngOnInit() { 
    let childComponentType: Type = null; 
    switch (this.typeComponent) { 
    case 1: 
     childComponentType = ChildComponentOne; 
     break; 
    case 2: 
     childComponentType = ChildComponentTwo; 
     break; 
    case 3: 
     childComponentType = ChildComponentThree; 
     break; 
    } 

    if (childComponentType != null) { 
    let factory = this._resolver.resolveComponentFactory(childComponentType); 
    let instance: ComponentRef<any> = this.container.createComponent(factory); 

    childComponent.instance.value = this.someValue; 
    } 
} 

你也可以把所有的3个例组件的继承公共基类,有你的共同属性,方法和@Output S:

可以进一步降低复制代码中的这种方式类。这样,当每个组件共享一个共同的行为时,您可以读取值并订阅EventEmitter。

东西沿着这些路线:

export class ChildComponentBaseClass { 
    @Input() value; 
} 

@Component({...}) 
export class ChildComponentOne<ChildComponentBaseClass> { 
    ... 
} 
@Component({...}) 
export class ChildComponentTwo<ChildComponentBaseClass> { 
    ... 
} 

ngOnInit() { 
    let childComponentType: Type = null; 
    switch (this.typeComponent) { 
    case 1: 
     childComponentType = ChildComponentOne; 
     break; 
    case 2: 
     childComponentType = ChildComponentTwo; 
     break; 
    case 3: 
     childComponentType = ChildComponentThree; 
     break; 
    } 

    if (childComponentType != null) { 
    let factory = this._resolver.resolveComponentFactory(childComponentType); 
    let instance: ComponentRef<ChildComponentBaseClass> = this.container.createComponent<ChildComponentBaseClass>(factory); 

    // instance.value is now properly typed! 
    childComponent.instance.value = this.someValue; 
    } 
}