I have a component with an SVG element, I am trying to separate the parts of that SVG into different components. The nested components need to be created dynamically from the parent component, this is because of the fact I am building the whole SVG graphic from a json file that determines which nested components (SVG nested shapes) need to be added.
To create the components dynamically I am using ComponentFactoryResolver and the ViewContainerRef from @angular/core
@Component({
selector: 'skick-player',
templateUrl: './player.component.html',
styleUrls: ['./player.component.scss'],
})
export class PlayerComponent implements OnInit, AfterViewInit {
@ViewChild('svgContainer', { read: ViewContainerRef }) container;
constructor( private resolver: ComponentFactoryResolver) {}
performFrame() {
....
//Add nested component
const factory = this.resolver.resolveComponentFactory(
BackDropItemComponent
);
const componentRef = this.container.createComponent(factory);
componentRef.instance.imagePath = objectUrl;
}
}
});
}
The problem is that angular wraps the nested component within a div:
<div _nghost-qon-c42="" skick-back-drop-item="" class="ng-star-inserted">
So it is not rendered because of the special element tags created. If that div element is removed, it renders the nested SVG properly.
I know i can render the nested component as a directive and it would work, something like this:
<svg>
<svg:g skick-back-drop-item />
</svg>
but in my use case, the controller needs to be rendered dynamically from the parent component, so that approach does not work for me.
Maybe is there a way to render (add the nested controller) as a directive from the parent component pro-grammatically (bear in mind the nested component has @input properties) ?
or
Is it possible to have invisible component containers? Render the content of the nested component without any container?
Parent template:
<div class="patch-overlay" cdkDrag>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:svgjs="http://svgjs.dev/svgjs" width="100%" height="100%">
<<ng-container #svgContainer></ng-container>>
</svg>
</div>
Nested Component Template (Example):
<svg width="400" height="110">
<rect [attr.width]="width" height="100" style="fill:rgb(0,0,255);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>
[and]:selector: '[skick-back-drop-item]',you can appli to any html tag - Eliseo