Angular2 SVG xlink:href

前端 未结 3 1138
终归单人心
终归单人心 2020-12-08 04:27

I have component for rendering SVG icon:

import {Component, Directive} from \'angular2/core\';
import {COMMON_DIRECT         


        
相关标签:
3条回答
  • 2020-12-08 04:53

    I think it can be solved using angular pipe feature.

    <use attr.xlink:href={{weatherData.currently.icon|iconpipe}}></use>
    

    Explanation This pipe will

    1. Pass the parsed response value to the pipe
    2. Return the complete svg path
    3. attr.xlink:href= will get the expected path & svg will rendered in html page

    here is pipe typescript code

    import { PipeTransform, Pipe } from '@angular/core';
    
    @Pipe({
        name: 'iconpipe'
    })
    export class IconPipe implements PipeTransform {
        constructor() { }
    
        transform(value: any) {
            let properIconName = undefined;
    
            switch (value) {
                case 'clear-day':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#sun';
                    break;
                case 'clear-night':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#night-1';
                    break;
                case 'partly-cloudy-day':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#cloudy';
                    break;
    
                case 'partly-cloudy-night':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#night';
                    break;
    
                case 'cloudy':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#cloud';
                    break;
    
                case 'rain':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#rain';
                    break;
    
                case 'sleet':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#snowflake';
                    break;
                case 'snow':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#snowing';
                    break;
    
                case 'wind':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#storm';
                    break;
                case 'fog':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#sun';
                    break;
                case 'humid':
                    properIconName = '/assets/images/weather-SVG-sprite.svg#sun';
                    break;
                default:
                    properIconName = '/assets/images/weather-SVG-sprite.svg#summer';
            }
            return properIconName;
        }
    }
    
    0 讨论(0)
  • 2020-12-08 05:02

    I was still having issues with the attr.xlink:href described by Gunter so I created a directive that is similar to SVG 4 Everybody but is specific for angular2.

    Usage

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

    Explanation

    This directive will

    1. Load icons/icons.svg over http
    2. Parse the response and extract path info for #menu-dashboard
    3. Add the parsed svg icon to the 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))
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 05:06

    SVG elements doen't have properties, therefore attribute binding is required most of the time (see also Properties and Attributes in HTML).

    For attribute binding you need

    <use [attr.xlink:href]="iconHref">
    

    or

    <use attr.xlink:href="{{iconHref}}">
    

    Update

    Sanitization might cause issues.

    See also

    • https://github.com/angular/angular/issues/9510)
    • https://angular.io/docs/ts/latest/api/platform-browser/index/DomSanitizationService-class.html

    Update DomSanitizationService is going to be renamed to DomSanitizer in RC.6

    Update this should be fixed

    but there is an open issue to support this for namespaced attributes https://github.com/angular/angular/pull/6363/files

    As work-around add an additional

    xlink:href=""
    

    Angular can update the attribute but has issues with adding.

    If xlink:href is actually a property then your syntax should work after the PR was added as well.

    0 讨论(0)
提交回复
热议问题