In Angular 5, how to get access to dynamically added child components from parent component?

Viewed 2123

I am developing an Ionic + Angular 5 project.

I need to dynamically load some components. Following the Dynamic Component Loader Example in the Angular documentation I am able to successfully load components and displayed them.

I have a need, however, to be able to loop through the loaded components.

I can easily maintain my own list of components in the parent as I create and destroy the child components but it seems to me that that's ugly and not the "Angular Way".

After much experimentation and research it seems that I cannot use @ViewChildren to access dynamically added components since they have their own views. ViewChildren not finding Dynamically components

Is this correct?

I am able to use viewContainerRef.get() to iterate over the child views and retrieve ViewRefs. But there doesn't seem to be a way to get a reference to the component given a ViewRef?

I notice the 'rootNodes' property of the ViewRef however that property is not documented in the Angular docs View Ref However, it is documented in the EmbeddedViewRef docs Embedded View Ref but that still doesn't seem to give me access to the component.

So the question is when I have a parent that dynamically adds child components how can I from the parent loop through the child components (so I can call one of my methods in the child)? My suspicion is that I am missing something stupid simple, have some fundamental misconception, or that there is a different pattern that I should be using.

I've modified the Dynamic Component Loader example to highlight what I am trying to do.Modified Dynamic Component Loader

1 Answers

So, I thought about this and a clean way to do this (in my opinion), is to pass create a property on the parent component, such as parentContext and to pass the data or method into this object.

Example - in parent component, you can even pass a method into your child component and it will run within the context of the parent.:

  gotoDetail(hero: Hero): void {
    this.entry.clear();
    const factory = this.resolver.resolveComponentFactory(DynamicModalChildComponent);
    this.dynamicModalComponentRef = this.entry.createComponent(factory);
    this.dynamicModalComponentRef.instance.hero = hero;
    // Pass parent context to child in order to close modal hierarchically (parent/child component relationship).
    // This approach is less verbose and makes it easier to unit test than a service in my opinion.
    this.dynamicModalComponentRef.instance.parentContext = () => this.destroyComponent();
}

Related