I have an AppComponent
which holds a list of ShapeComponents
. I implemented some Components which extends the ShapeComponent
like LineComponent
, CircleComponent
, RectangleComponent
. Each of them has its own ng-template
with #shapeTemplate
.
In my app.component.html
I want to iterate over the list of ShapeComponents
and display each ng-template
(from LineComponent
, CircleComponent
etc).
so I have
shapes: ShapeComponent[] = []
which hold a LineComponent, CircleComponent etc
I want to something like this
<div *ngFor="let shape of shapes">
<!-- How to display the ng-template from for example LineComponent or Circle -->
</div>
I thought using @ViewChildren or @ContentChildren would be useful but no idea how to deal with that
I found the solution. Actually I found an excellent post on github
https://github.com/shivs25/angular5-canvas-drawer. I took this solution to implement my own.
So all the credits go to Billy Shivers. Well done.
Here is the solution
The settings for line and circle can be dynamic set, below is just an example of a line and circle
CircleComponent and HTML template
html
LineComponent and HTML template
html
The ShapeComponent and HTML
html : none
The enum for component types
The ShapeHolderComponent
html, set height in width in css for the svg
And the most import part of it, the directive
And the app.component html
The app.component
And the app.module.ts
And a final screen shot of my app
I hope you find this answer usefull and can use it in your own app. The idea is to create dynamic templates views
In this case the best and also officially suggested approach is to use Dynamic Forms.
In the documentation you'll find some useful tips
I've done something similar recently. Here is the final stackblitz
First, I create a ShapeComponent
It's template has a
ng-template
so that we can ref to it, andng-content
so consumers of this component can project their content in.With
@ViewChild(TemplateRef)
you can get a reference ofng-template
and whatever is inside of it because ofng-content
.Let's create a
LineComponent
and
CircleComponent
Both components extend
ShapeComponent
and provide it according to themselves. So that whenever someone tries to injectShapeComponent
, they will get aLineComponent
or aShapeComponent
.Finally, let's create a
ShapeHolderComponent
which will glue all this togetherYou can list of
ShapeComponent
s withContentChildren
. Since, everyShapeComponent
provides themselves, we can get a list of them and use theirtemplate
s.Finally, let's use all of this within
AppComponent
The output is
There is a solution to display components, but it is quite complex and not my recommendation.
The "angular-style" solution for your issue is this:
models
in this example.typeOf
). Let's call ifshape
. You could also use an enumeration, if you prefer.ngFor
and create a component for each one of them.The HTML-Template might look like this
See the full, working example on stackblitz.