Как получить экземпляр Component из ViewContainerRef.get() для компонентов, созданных динамически
Краткое изложение того, чего я пытаюсь достичь
- динамически добавлять компоненты в
ViewContainerRef
(сделанный) - инициализировал эти динамические компоненты со свойствами (готово)
- получить доступ к динамически создаваемым экземплярам Component, чтобы я мог принимать решения на основе того, что есть.
проблема
- при динамическом добавлении компонентов они добавляются в
ViewContainerRef
ViewContainerRef
предлагает такие методы, какget(index)
это возвращениеViewRef
.ViewRef
не имеет никакого отношения кComponent
например, затрудняет получение необходимых данных
Вот ссылка на Stackblitz с рабочим кодом, показанным ниже (для динамического создания компонентов)
то
appComponent
начинается с создания нескольких компонентов с использованием
ComponentFactoryResolver
, и добавив их в
ViewChild
определено в шаблоне. каждый
DynamicComponent
инициализируется
id
значение свойства, на которое мы пытаемся сослаться после создания
@Component({
selector: "my-app",
template: `
<h3>Retrieving Component Reference for Dyamic Compnents</h3>
<button (click)="getCompRef()">Get References</button>
<div>
<ng-container #childCont></ng-container>
</div>
<div>
<small>List out the Ids from the dynamic components</small> <br />
{{ createdItemIds | json }}
</div>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent implements AfterViewInit {
@ViewChild("childCont", { read: ViewContainerRef })
childCont: ViewContainerRef;
createdItemIds: string[] = [];
itemLimit = 5;
constructor(
private fr: ComponentFactoryResolver,
private cdr: ChangeDetectorRef
) {}
ngAfterViewInit(): void {
for (let i = 0; i < this.itemLimit; i++) {
const factory = this.fr.resolveComponentFactory(DynamicComponent);
const compRef = this.childCont.createComponent(factory, i);
// Set the id of the instance so that we can use it later
compRef.instance.id = i + 1;
this.cdr.detectChanges();
}
}
...
}
то
DynamicComponent
добавление довольно просто. для упрощения он содержит только один
id
собственность, которую мы пытаемся получить
@Component({
selector: "dynamic-component",
template: `
<div>Dynamic Component: {{ id }}</div>
`,
styles: [``]
]
})
export class DynamicComponent {
id: number;
}
Пока все хорошо.
- Компоненты создаются динамически
- экземпляры компонента инициализируются идентификатором, который мы можем видеть по жирности, отображаемой в пользовательском интерфейсе
проблема возникает при попытке получить свойство ID из компонентов DynamicallyCreated.
в
AppComponent
, когда пользователь нажимает кнопку,
getCompRef()
вызывается метод, который проходит по каждому дочернему элементу
childCont (ViewContainerRef)
getCompRef(): void {
for (let i = 0; i < this.itemLimit; i++) {
const viewRef = this.childCont.get(i);
// How do I get at the instance of the view in order to obtain id?
// the view Ref doesn't provide access to the instance
// console.log(viewRef);
}
}
Тем не менее
ViewRef
вернулся из
ViewContainerRef.get()
является подклассом
ChangeDetectoreRef
и не содержит ссылки на рассматриваемый экземпляр.
Изучая эту проблему, он попытался пойти по пути использования
ViewChildren
чтобы получить создаваемые компоненты списка, но это не сработало из-за таких проблем, как
- https://github.com/angular/angular/issues/8785
- или примеры предполагают, что директива, используемая в
ViewChildren
selector
для компонента, который был предопределен в шаблоне - Я вижу много вопросов в отношении некоторых людей, которые хотят получить ViewRef, когда у них есть
Component.instance
, но в данной ситуации это бесполезно.
В конечном итоге мой вопрос:
- есть ли простой способ получить экземпляр Component из
ViewRef
что я скучаю
Любая помощь приветствуется.
благодарю вас.
1 ответ
Я мог сделать это, только отслеживая экземпляры этих компонентов в другом массиве.
@Component({
selector: "my-app",
template: `
<h3>Retrieving Component Reference for Dyamic Compnents</h3>
<button (click)="getCompRef()">Get References</button>
<div>
<ng-container #childCont></ng-container>
</div>
<div>
<small>List out the Ids from the dynamic components</small> <br />
{{ createdItemIds | json }}
</div>
`,
styleUrls: ["./app.component.css"]
})
export class AppComponent implements AfterViewInit {
@ViewChild("childCont", { read: ViewContainerRef })
childCont: ViewContainerRef;
createdItemIds: string[] = [];
itemLimit = 5;
private dynamicComponentsArray: ComponentRef<DynamicComponent>[] = [];
constructor(
private fr: ComponentFactoryResolver,
private cdr: ChangeDetectorRef
) {}
ngAfterViewInit(): void {
for (let i = 0; i < this.itemLimit; i++) {
const factory = this.fr.resolveComponentFactory(DynamicComponent);
const compRef = this.childCont.createComponent(factory, i);
// Set the id of the instance so that we can use it later
compRef.instance.id = i + 1;
this.dynamicComponentsArray.push(compRef);
this.cdr.detectChanges();
}
}
getCompRef(): void {
for (let i = 0; i < this.itemLimit; i++) {
const viewRef = this.childCont.get(i);
if (this.dynamicComponentsArray.length > 0) {
for (let i = 0; i < this.dynamicComponentsArray.length; i++) {
const componentRef = this.dynamicComponentsArray[i];
const component = (componentRef) as ComponentRef<DynamicComponent>;
let value = component.instance.id;
}
}
}
}
}