J'ai un composant pour le rendu de l'icône SVG:
import {Component, Directive} from 'angular2/core';
import {COMMON_DIRECTIVES} from 'angular2/common';
@Component({
selector: '[icon]',
directives: [COMMON_DIRECTIVES],
template: `<svg role="img" class="o-icon o-icon--large">
<use [xlink:href]="iconHref"></use>
</svg>{{ innerText }}`
})
export class Icon {
iconHref: string = 'icons/icons.svg#menu-dashboard';
innerText: string = 'Dashboard';
}
Cela déclenche une erreur:
EXCEPTION: Template parse errors:
Can't bind to 'xlink:href' since it isn't a known native property ("<svg role="img" class="o-icon o-icon--large">
<use [ERROR ->][xlink:href]=iconHref></use>
</svg>{{ innerText }}"): SvgIcon@1:21
Comment définir la dynamique xlink:href
?
Les éléments SVG n'ont pas de propriétés, donc la liaison d'attribut est requise la plupart du temps (voir aussi Propriétés et attributs en HTML ).
Pour la liaison d'attribut dont vous avez besoin
<use [attr.xlink:href]="iconHref">
ou
<use attr.xlink:href="{{iconHref}}">
Mise à jour
La désinfection peut provoquer des problèmes.
Voir également
Mise à jour DomSanitizationService
va être renommé DomSanitizer
dans RC.6
Mise à jour cela devrait être corrigé
mais il existe un problème ouvert pour le prendre en charge pour les attributs d'espaces de noms https://github.com/angular/angular/pull/6363/files
Comme solution de contournement, ajoutez un
xlink:href=""
Angular peut mettre à jour l'attribut mais a des problèmes avec l'ajout.
Si xlink:href
est en fait une propriété, votre syntaxe devrait également fonctionner après l'ajout du PR.
J'avais toujours des problèmes avec le attr.xlink: href décrit par Gunter donc j'ai créé une directive similaire à SVG 4 Everybody mais spécifique à angular2.
<div [useLoader]="'icons/icons.svg#menu-dashboard'"></div>
Cette directive
import { Directive, Input, ElementRef, OnChanges } from '@angular/core';
import { Http } from '@angular/http';
// Extract necessary symbol information
// Return text of specified svg
const extractSymbol = (svg, name) => {
return svg.split('<symbol')
.filter((def: string) => def.includes(name))
.map((def) => def.split('</symbol>')[0])
.map((def) => '<svg ' + def + '</svg>')
}
@Directive({
selector: '[useLoader]'
})
export class UseLoaderDirective implements OnChanges {
@Input() useLoader: string;
constructor (
private element: ElementRef,
private http: Http
) {}
ngOnChanges (values) {
if (
values.useLoader.currentValue &&
values.useLoader.currentValue.includes('#')
) {
// The resource url of the svg
const src = values.useLoader.currentValue.split('#')[0];
// The id of the symbol definition
const name = values.useLoader.currentValue.split('#')[1];
// Load the src
// Extract interested svg
// Add svg to the element
this.http.get(src)
.map(res => res.text())
.map(svg => extractSymbol(svg, name))
.toPromise()
.then(svg => this.element.nativeElement.innerHTML = svg)
.catch(err => console.log(err))
}
}
}