Patrick
Patrick

Reputation: 457

Dynamically created component gets added as sibling

I'm working on a Ionic/Angular project where i'm trying to add components dynamically to a page. To create the component i am using the Angulars ComponentFactoryResolver. When adding the components to the view, they get added as siblings of the target container and not as children.

instrument.page.ts

@Component({
    selector: 'app-instruments',
    templateUrl: './instruments.page.html',
    styleUrls: ['./instruments.page.scss'],
})
export class InstrumentsPage implements AfterViewInit {

    instruments: Instrument[];

    @ViewChild('instrumentscontainer', { read: ViewContainerRef }) entry: ViewContainerRef;

    constructor(
        private data: DataService,
        private resolver: ComponentFactoryResolver
    ) {
        this.instruments = data.getInstruments();
    }

    ngAfterViewInit() {
        this.createComponents();
    }

    createComponents() {
        this.entry.clear();
        const factory = this.resolver.resolveComponentFactory(InstrumentCardComponent);
        this.data.getData().forEach((organization: Organization) => {
            organization.getGroups().forEach((group: Group) => {
                group.getFields().forEach((field: Field) => {
                    field.getInstruments().forEach((instrument: Instrument) => {
                        let component = this.entry.createComponent(factory);
                        component.instance.instrument = instrument;
                        component.instance.field = field;
                        console.log(component);
                    });
                });
            });
        });
    }
}

instrument.page.html

<ion-content #instrumentscontainer>
</ion-content>

enter image description here

Upvotes: 4

Views: 560

Answers (2)

Ron Flores
Ron Flores

Reputation: 11

I was having the same issue, and what I found out is that I wasn't referencing the container on the @ViewChild decorator. So I had a container that was not defined as the entry point.

In the example above, I didn't have the view: ViewContainerRef element so it would load always outside the container (it was creating a new container outside the element). I resolved it by using:

@ViewChild('ref', { read: ViewContainerRef, static: true }) entry: ViewContainerRef;

Then when loading the component,

const componentRef = this.entry.createComponent(ShipmentDetailsComponent);

And in the template,

<ng-container #ref></ng-container>

Hope this helps someone.

Upvotes: 1

Patrick
Patrick

Reputation: 457

I solved this issue by placing

<ng-container #instrumentcontainer></ng-container> 

inside the ion-content element from what i understood gets removed from the DOM on runtime.

Upvotes: 2

Related Questions