2016-12-14 114 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; 
    } 
}