I've been reading through many different blog posts and topics on here to see how or even if what I'm trying to do with templates can be done, but have not found anything that works.
We have an icon component that is quite simple in structure which is set up by simply using the component and specifying which icon and size is needed in the template using it:
import {Component, Input} from '@angular/core';
@Component({
selector: 'comp-icon',
template: `
<span class="{{ class }}" *ngIf="icon === 'error'" >
<svg [attr.height]="size" viewBox="0 0 48 48" [attr.width]="size" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
</span>
<span class="{{ class }}" *ngIf="icon === 'success'" >
<svg [attr.height]="size" viewBox="0 0 48 48" [attr.width]="size" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"></svg>
</span>
`
})
export class IconComponent {
@Input() icon: string;
@Input() size: number;
@Input() class: string;
constructor() {
}
}
The problem is that the above repeats for many more lines and we are trying to include the ability to add custom svg images to the list from the various applications that will be using the library that is implementing this component. So far this is what I've managed which basically illustrates what we're trying to accomplish:
import {Component, Input, OnInit, ViewChild} from '@angular/core';
import {Icons} from './icons';
@Component({
selector: 'comp-icon',
template: `
<span class="{{ class }}">
<ng-container [ngTemplateOutlet]="iconContent"></ng-container>
</span>
`
})
export class IconComponent implements OnInit {
@Input() icon: string;
@Input() size: number;
@Input() class: string;
@ViewChild('iconContent') iconContent: any;
constructor() {
}
ngOnInit() {
this.iconContent = (Icons.find(icon => icon.name === this.icon) || { name: '', content: '' }).content;
}
}
And the corresponding icons.ts looks like this:
export interface IIcon {
name: string;
content: string;
}
export const Icons: IIcon[] = [
{
name: 'error',
content: `<svg [attr.height]="{SIZE}" [attr.width]="{SIZE}" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
</svg>`
},
{
name: 'success',
content: `<svg [attr.height]="{SIZE}" [attr.width]="{SIZE}" viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
</svg>`
},
];
Is it at all possible to dynamically specify the contents of a section of a component in this way, in this case the svg? I've read some about directives being able to accomplish this, but nothing really sticks out or I haven't really figured out how.