Angular2 动态组件的最佳方式
Angular2 Best way for dynamic component
我想知道创建动态组件的最佳方式(性能)是什么。
我都试过了,但我无法确定我应该使用哪一个。
我的 component.html 容器中有一个 ng-switch
@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;
}
}
}
这是一个简单的例子,在我的应用程序中我有大量的动态组件。
提前谢谢你们的回答。
虽然这两种方式都是可行的,但为了 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 个示例组件都继承一个共同的基础 class,并在基础 class 中拥有共同的属性、方法和 @Output
。通过这种方式,您可以在每个组件共享共同行为时读取值并订阅 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;
}
}
我想知道创建动态组件的最佳方式(性能)是什么。 我都试过了,但我无法确定我应该使用哪一个。
我的 component.html 容器中有一个 ng-switch
@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;
}
}
}
这是一个简单的例子,在我的应用程序中我有大量的动态组件。
提前谢谢你们的回答。
虽然这两种方式都是可行的,但为了 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 个示例组件都继承一个共同的基础 class,并在基础 class 中拥有共同的属性、方法和 @Output
。通过这种方式,您可以在每个组件共享共同行为时读取值并订阅 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;
}
}