3

什么是更好的?使用 ngFor 或 ViewContainerRef 动态创建组件?有什么区别?

例如,如果我有一个按钮来创建一个新元素,每次按下它都会生成一个新组件。

1)第一个选项如下

items: number[] = [];

addItem() {
  this.items.push(1);
}

<my-component *ngFor="let item of items"></my-component>

2)第二个选项

@ViewChild('viewContainerRef', { read: ViewContainerRef }) VCR: ViewContainerRef;

  index: number = 0;

  componentsReferences = [];

  constructor(private CFR: ComponentFactoryResolver) {
  }

  createComponent() {

    let componentFactory = this.CFR.resolveComponentFactory(ChildComponent);
    let componentRef: ComponentRef<ChildComponent> = this.VCR.createComponent(componentFactory);
    let currentComponent = componentRef.instance;

    currentComponent.selfRef = currentComponent;
    currentComponent.index = ++this.index;

    // prividing parent Component reference to get access to parent class methods
    currentComponent.compInteraction = this;

    // add reference for newly created component
    this.componentsReferences.push(componentRef);
  }

  remove(index: number) {

    if (this.VCR.length < 1)
      return;

    let componentRef = this.componentsReferences.filter(x => x.instance.index == index)[0];
    let component: ChildComponent = <ChildComponent>componentRef.instance;

    let vcrIndex: number = this.VCR.indexOf(componentRef)

    // removing component from container
    this.VCR.remove(vcrIndex);

    this.componentsReferences = this.componentsReferences.filter(x => x.instance.index !== index);
  }

第一个选项是迭代数组并通过带有 ngFor 的组件显示其内容的典型方式。第二个选项使用 ViewContainerRef 而不是 ngFor。可以在以下链接中看到一个示例。

https://stackblitz.com/edit/add-or-remove-dynamic-component?file=src%2Fapp%2Fparent%2Fparent.component.ts

https://stackblitz.com/edit/angular-jukjib

4

1 回答 1

1

根据我的理解:

如果你想插入新的组件或模板,你需要告诉 Angular 把这个元素放在哪里。这就是 ViewContainerRef 是什么。它是一个 DOM 元素(容器),您可以在其中将新组件作为该元素的兄弟元素。

*ngFor Angular 中的指令。NgFor 是一个内置的模板指令,它可以很容易地遍历数组或对象之类的东西,并为每个项目创建一个模板。... of users 意味着我们将迭代应该在我们的组件中可用的用户可迭代

总之,如果你想插入一个新的组件或模板作为兄弟,你可以使用ViewContainerRef,如果你只有一个迭代像数组或对象这样的东西并在同一个组件中创建一个模板,使用ngFor

我希望这会有所帮助。欢迎大家指正

于 2020-01-31T16:19:46.280 回答