web-dev-qa-db-fra.com

Angular2 SVG xlink: href

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?

37
tomaszbak

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.

66
Günter Zöchbauer

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.

Usage

<div [useLoader]="'icons/icons.svg#menu-dashboard'"></div>

Explication

Cette directive

  1. Charger des icônes/icons.svg sur http
  2. Analyser la réponse et extraire les informations de chemin pour # menu-dashboard
  3. Ajouter l'icône svg analysée au html

Code

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))
        }
    }
}
3
Ryan Hansen