bicarlsen
bicarlsen

Reputation: 1371

Dynamic Child Component in Angular

I am building an app with a consistent design pattern for lists of elements. If I have an object of type A, I create AComponent which accepts a as an input, then create another component to iterate over a list of A's, AListComponent. Then if I have an object B, I need to do the same thing. It seems like I should be able to make an ObjectListComponent passing in the class of the object I want to iterate over, to keep my code DRY.

For example, given

AComponent Controller

...

@Input
a: A;
...

AComponent HTML

<div>{{ a.name }}</div>

AListComponent Controller

...

@Input()
aList: A[];
...

AListComponent HTML

<div *ngFor='let aObj of aList'>
    <app-a [a]='aObj'></app-a>
</div>

How can we abstract the AListComponent to an ObjectListComponent?

ObjectListComponent Controller

...

@Input()
type: any;

@Input()
objects: <type>[]

objectComponent: any;

ngOnInit () {
  this.objectComponent = <get object component from type>
}

ObjectListComponent HTML

<div *ngFor='let obj of objects'>
    <app-objectComponent [object]='obj'></app-objectComponent>
</div>

where the ObjectListComponent would be used as

...

<app-object-list [type]='A' objects='aList'></app-object-list>
...

Upvotes: 4

Views: 2939

Answers (1)

Shashank Vivek
Shashank Vivek

Reputation: 17494

Thanks for providing a demo code, Take a look at this demo code

The main logic is there in object-list.components.ts

ngAfterViewInit(){
     const component_obj = this.getComponentType(this.objects[0]);
      this.containers.map(
      (vcr: ViewContainerRef, index: number) => {
        const factory = this.resolver.resolveComponentFactory(
          component_obj);
        const componentRef = vcr.createComponent(factory);
        componentRef.instance['data'] = this.objects[index];
        this.cd.detectChanges()
      }
    )
 }

Basically, I have done is:

  1. a.component.html : To handle logic of object interface A

  2. b.component.html : To handle logic of object of type interface B

  3. You can switch between 2 object types in home.component.html

Shows Component A

<app-object-list [objects]='aList'></app-object-list>

Shows Component B

<app-object-list [objects]='bList'></app-object-list>

You can improve the logic to check and determine the type. That part of the code can be improved

Upvotes: 2

Related Questions