【问题标题】:Angular2 Best way for dynamic componentAngular2动态组件的最佳方式
【发布时间】:2016-12-14 16:34:05
【问题描述】:

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

在我的 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;
    }
  }
}

这是一个简单的例子,在我的应用程序中我有大量的动态组件。

提前感谢您的回答。

【问题讨论】:

  • 在我的第二个例子中,很酷的是我可以在我的 childComponent 上有一个实例,我可以轻松地操作实例和调用方法。在我看来,这更像是面向对象的方式。

标签: angular angular2-components


【解决方案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 个示例组件都继承一个公共基类,并在基类中包含您的公共属性、方法和 @Outputs。这样,当每个组件共享一个共同行为时,您就可以读取值并订阅 EventEmitters。

类似的东西:

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;
  }
}

【讨论】:

  • 摆脱冗长开关的视觉改进是使用字典。 const typeToComponentMap = { 1: ChildComponentTwo, 2: ChildComponentTwo, 3: ChildComponentThree };然后使用: let factory = this._resolver.resolveComponentFactory(typeToComponentMap[this.typeComponent]);
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
  • 2016-09-21
  • 1970-01-01
  • 1970-01-01
  • 2017-02-06
  • 1970-01-01
相关资源
最近更新 更多