4

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>
...
8
  • U need to provide more info. How much diff are the AComponent vs BComponent ? I mean, are they all similar (css, functions) ? what is the purpose of this.objectComponent , how are you planning to use it? If the only diff is the type then create interface ICanvasComponentInput and define type as obj: A | B inside it. use it in ObjectListComponent @Input param. (Try to give more generic name to ObjectListComponent) Commented Jan 5, 2020 at 12:25
  • The idea is that ObjectListComponent should be able to iterate over an arbitrary list of models because the component representing the model is passed in through the type attribute. this.objectComponent would be the component representing the type of objects in the list of objects passed in through the objects attribute. Commented Jan 5, 2020 at 19:36
  • I think I got the question little bit. It would be really helpful for me if you can create a demo on stackblitz.com . I'll take it up from there Commented Jan 6, 2020 at 5:10
  • It says that the requested page cant be found Commented Jan 8, 2020 at 3:33
  • Sorry about that, I haven't used StackBlitz before, so still getting used to it. This should work: stackblitz.com/github/bicarlsen/temp Commented Jan 8, 2020 at 9:04

1 Answer 1

2

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

Sign up to request clarification or add additional context in comments.

1 Comment

I noticed there is a slight error occurring in that one of the elements of the list does not appear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.