У меня есть этот код в 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
);
}
}
Проблема в Angular 16 заключается в том, что vcrIndex всегда имеет значение -1, если не найден.
let vcrIndex: number = this.VCR.indexOf(componentRef as any);
// removing component from container
this.VCR.remove(vcrIndex);
Есть какие-нибудь предложения или как это исправить, не изменяя способ создания динамических компонентов? Я пробовал несколько вещей, например добавление индекса или идентификатора, но так и не смог решить проблему.
Спасибо
Я посмотрел, отличается ли структура видеомагнитофона, и мог бы добавить идентификатор и выполнить поиск вручную, но не смог.





Не знаю, почему именно это сработало раньше, думаю, это было просто совпадение. 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);