I would like to implement a component acting like a container with dynamically added children components. The type and number of children components should be configured on server side.
So Models arrived from
the server could look like this:
export class ModelBase {
public data: any;
}
export class ModelA extends ModelBase {
public dataA: any;
}
export class ModelB extends ModelBase {
public dataB: any
}
Simplified components could be like this:
@Component({
selector: "component-base"
})
export class BaseComponent {
@Input() model: ModelBase;
}
@Component({
selector: "component-a",
template: "<div>component-a</div>"
})
export class AComponent extends BaseComponent {
@Input() model: ModelBase;
}
@Component({
selector: "component-b",
template: "<div>component-b</div>"
})
export class BComponent extends BaseComponent {
@Input() model: ModelBase;
}
And here is the Application and how I would like to work with my components:
@Component({
selector: 'app',
template: `
<div *ngFor="#model of models">
<component-base [model]="model"></component-base>
</div>
`
})
export class App {
}
I want component-base
will be replaced with the concrete implementation based on model
type. For example, with component-a.
Does workflow like this is possible to implement with Angular 2?
There might be a better API for this functionality coming: https://github.com/angular/angular/pull/11235.
In the meantime, check out https://stackoverflow.com/a/36325468/5307109. You'll likely have to modify it so that you can pass data through it to your destination component and call a custom component hook on load.
Using the wrapper described above, your ComponentBase
will have a template of its own and inject each model's associated component into the wrapper.
export class ModelA extends ModelBase {
dataA: any;
component: any = AComponent;
}
@Component({
selector: "component-base",
template: `
<dcl-wrapper [type]="model.component" [init-data]="model"></dcl-wrapper>
`
})
export class BaseComponent {
@Input() model: ModelBase;
}
@Component({
selector: "component-a",
template: "<div>component-a</div>"
})
export class AComponent {
@Input() model: ModelBase;
/**
* Custom hook you might create in DclWrapper.
*/
onDclInit(model: ModelBase) : void {
this.model = model;
}
}