添加和删除动态组件Angular

问题描述 投票:0回答:1

我在 Angular 12 中有这段代码,它运行得很好。将版本从 12 更改为 16 时出现问题。

import {
  ComponentRef,
  ComponentFactoryResolver,
  ViewContainerRef,
  ViewChild,
  Component,
ViewRef
} from "@angular/core";
import { ChildComponent } from "../child/child.component";

@Component({
  selector: "app-parent",
  templateUrl: "./parent.component.html",
  styleUrls: ["./parent.component.css"]
})
export class ParentComponent {
  @ViewChild("viewContainerRef", { read: ViewContainerRef })
  VCR: ViewContainerRef;

  child_unique_key: number = 0;
  componentsReferences = Array<ComponentRef<ChildComponent>>()

  constructor(private CFR: ComponentFactoryResolver) {}

  createComponent() {
    let componentFactory = this.CFR.resolveComponentFactory(ChildComponent);

    let childComponentRef = this.VCR.createComponent(componentFactory);

    let childComponent = childComponentRef.instance;
    childComponent.unique_key = ++this.child_unique_key;
    childComponent.parentRef = this;

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

  remove(key: number) {
    if (this.VCR.length < 1) return;

    let componentRef = this.componentsReferences.filter(
      x => x.instance.unique_key == key
    )[0];

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

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

    // removing component from the list
    this.componentsReferences = this.componentsReferences.filter(
      x => x.instance.unique_key !== key
    );
  }
}

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

Angular 16 中的问题是,当未找到时,vcrIndex 始终为 -1。

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

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

有什么建议或者如何解决这个问题而不必修改动态组件的创建方式? 我尝试了几种方法,例如添加索引或标识符,但仍然无法解决问题。

谢谢

我查看了 VCR 结构是否不同,我可以添加标识符并手动搜索它,但我做不到。

angular indexing dynamic components
1个回答
0
投票

不知道为什么它之前会起作用,猜测这只是一个巧合。

this.VCR.indexOf
实际上期望
ViewRef
并且你传递了
ComponentRef
并将其投射到
any

解决方法非常简单,您只需将

componentRef.hostView
传递给
VCR.indexOf
:

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

这是一个使用 Angular 17 的工作演示


以防万一,

ComponentFactoryResolver
很久以前就已被弃用(v13),您可以将组件类型直接传递给
this.VCR.createComponent

let childComponentRef = this.VCR.createComponent(ChildComponent);
© www.soinside.com 2019 - 2024. All rights reserved.