2013-04-09 20 views
30

vorrei qualche input sull'utilizzo di XML namespace attributi con angolare.angolare ng-href e SVG xlink

Il problema è angolare viene fornito con un paio di direttive per gestire la scrittura attributi quali href e src quando angolare ha analizzato le expresssions (altrimenti il ​​browser cercherà di caricare {{mymodel.myimage}} come URL)

https://github.com/angular/angular.js/blob/master/src/ng/directive/booleanAttrs.js#L329

Il problema che sto affrontando è che sto usando angolare per generare svg insieme a D3 e dato che l'angolare non ha un modo di emettere xlink:href ero bloccato.

ho creato una direttiva personalizzato che emette xlink: href

app.directive('ngXlinkHref', function() { 
    return { 
    priority: 99, 
    restrict: 'A', 
    link: function (scope, element, attr) { 
     var attrName = 'xlink:href'; 
     attr.$observe('ngXlinkHref', function (value) { 
     if (!value) 
      return; 

     attr.$set(attrName, value); 
     }); 
    } 
    }; 
}); 

demo completa: http://plnkr.co/edit/cMhGRh

Ma sembra che se non aggiungere manualmente xlink: href per l'elemento, l'immagine svg non renderà.

Qualche suggerimento su come gestire meglio namespace XML/svg insieme angolare sarebbe molto apprezzato.

+0

non ho trovato una risposta alla tua domanda, ma vi ringrazio per la pubblicazione del Plunker. L'ho usato per il mio binding SVG angolare. –

risposta

49

Puoi usare ng-attr-<some attribute>

ng-attr-xlink:href="{{xxx}}" funziona per me.


Si noti inoltre che è necessario un valore xlink:href="" vuoto come valore iniziale. - Derek Hsu

+2

Questo non fornisce una risposta alla domanda. Per criticare o richiedere chiarimenti da un autore, lascia un commento sotto il loro post - puoi sempre commentare i tuoi post, e una volta che hai [reputazione] sufficiente (http://stackoverflow.com/help/whats-reputation) essere in grado di [commentare qualsiasi post] (http://stackoverflow.com/help/privileges/comment). – Siddharth

+4

@Siddharth, in realtà lo fa. La domanda non riguarda semplicemente le direttive personalizzate. Infatti, @Leon voleva un input sull'uso degli attributi xml namespaced con spigoli e suggerimenti su come gestire al meglio xml namespaces/svg insieme con angolare. Per risolvere il suo problema, stava persino scrivendo direttive personalizzate. Sottolineo che non sono necessarie direttive personalizzate. Angularjs ha già 'ng-attr' che fa il lavoro per lui. –

+0

Un upvote di @Leon contribuirà a invertire la mia decisione. – Siddharth

6

ho risolto lo stesso problema con i seguenti moduli:

Module per SVG:

var app = angular.module('Svgs', []); 

angular.forEach([ 
    { ngAttrName: 'ngXlinkHref', attrName: 'xlink:href' }, 
    { ngAttrName: 'ngWidth', attrName: 'width' }, 
    { ngAttrName: 'ngHeight', attrName: 'height' } 
], function (pair) { 

    var ngAttrName = pair.ngAttrName; 
    var attrName = pair.attrName; 

    app.directive(ngAttrName, function (IeHelperSrv) { 

     return { 

      priority: 99, 

      link: function (scope, element, attrs) { 

       attrs.$observe(ngAttrName, function (value) { 

        if (!value) return; 

        attrs.$set(attrName, value); 
        if (IeHelperSrv.isIE) element.prop(attrName, value); 
       }); 
      } 
     }; 
    }); 
}); 

Module per il rilevamento IE:

angular.module('IeHelper', []).factory('IeHelperSrv', function() { 

    return { 
     isIE: checkForIE.isIE, 
    } 
}); 

var checkForIE = { 
    init: function() { 
     this.isIE = (navigator.userAgent.indexOf('MSIE') != -1); 
    } 
}; 

checkForIE.init(); 

HTML:

<!-- image has initial fake source, width and height to force it to render --> 
<image xlink:href="~/Content/Empty.png" width="1" height="1" 
    ng-xlink-href="{{item.imageSrc}}" 
    ng-width="{{item.width}}" ng-height="{{item.height}}" 
    ng-cloak 
    /> 
+2

Quando xlink: href non funzionava per me, ho dovuto rileggere questo post. La chiave qui è che AVETE BISOGNO DI UN VALORE DI FALSO PER INIZIARE. Senza di esso, l'immagine non renderà nemmeno con l'attributo corretto. Lasciare questo commento per aiutare altri manichini TL; DR come me. Grazie Danny! – coblr

+0

@fractalspawn Siete i benvenuti. Stavo per aggiungere questo commento alla risposta, poi ho visto che ho già inserito questo commento sopra l'HTML :-) –

7

Mi sono imbattuto in un problema simile quando provavo a generare un valore per xlink:href legato al modello. Sulla base l'utente del prescelto <option> in un controllo <select>, stavo cercando di mostrare l'icona di uno SVG dinamica tramite l'attributo xlink:href dell'elemento <use>.

ho trovato nelle Problemi GitHub per AngularJS. Sulla base della discussione, sembra che, poiché esiste una soluzione alternativa valida, hanno effettivamente presentato una correzione spostandola nella milestone di Backlog.

Che fine ha funzionato per me è stato ispirato da questo JSBin:

http://jsbin.com/sigoleya/1/edit?html,js,output

Ecco il codice che ho usato nel mio modello:

<svg class="icon" data-ng-class="category.iconName"> 
    <use xlink:href="" data-ng-href="{{'#' + category.iconName}}"> 
</svg> 

dato un category.iconName di icon-music, per esempio, angolare imposta dinamicamente lo xlink:href su #icon-music, che fa riferimento all'elemento <svg id="icon-music"> più avanti nella stessa pagina.

Come altri hanno notato, la chiave è impostare un attributo vuoto xlink:href="" sull'elemento in cui si chiama la direttiva ngHref. L'ordine degli attributi non sembra avere importanza. Usare ng-attr-xlink:href="{{xxx}}" (come menzionato nella risposta di Derek Hsu) non ha funzionato per me.

Tutto ciò presuppone Angular 1.3.36.

+2

Grazie mille. –

0

I si è imbattuto in questo problema in cui stavo usando Ajax per caricare il spritesheet svg sulla pagina. Se avessi un messaggio nella pagina prima che il foglio di sprite fosse caricato, fallirebbe e non si risolverebbe una volta che lo spritesheet fosse disponibile. Qualsiasi aggiunta alla dom dopo il caricamento del foglio di sprite andava bene. Ho dovuto posticipare la messa degli oggetti nella dom fino a dopo il caricamento del foglio di sprite.

Questo ha riguardato solo IOS. Tutti gli altri browser non si sono interessati all'ordine.

0

Questo mi ha richiesto più tempo di quanto avrei voluto. Circa 20-30 minuti.

Se ho capito correttamente, qualsiasi caricamento non riuscito sull'elemento immagine sarà che rende quell'elemento inutile in futuro. Credo che sia qualcosa di simile @GeekyMonkey sta dicendo. Se il sistema di associazione angolare ha impostato xlink: href inizialmente su null, l'elemento Image non funzionerà più, anche se in futuro avremo un valore valido.

Ecco la soluzione, notare come ho spostato l'elemento immagine all'interno dell'elemento g, usando la direttiva ng-if. Questo assicura che ci legheremo contro l'immagine solo quando è disponibile un valore corretto.

<g ng-if="vm.svgMap.background != null"> 
    <image 
     ng-attr-xlink:href="{{vm.svgMap.background.image | trusted}}" 
     ng-attr-width="{{vm.svgMap.background.width}}" 
     ng-attr-height="{{vm.svgMap.background.width}}" 

     xlink:href="" 

     width="1" 
     height="1" 
     x="0" 
     y="0"></image> 
</g> 

Come altri hanno detto, anche l'ordine degli attributi è importante. Per garantire che angularJS ci permette di legare elemento di immagine, avremo anche fiducia che risorsa, ho fatto attraverso il filtro (che è quella in xlink: href):

2

Per chiunque altro abbia questo problema a causa di Angular/Angular UI Router in modalità HTML5, ho trovato una soluzione semplice per abilitare le icone sprite di svg a lavorare con il loro attributo xlink: href e il tag.

Gist è qui: https://gist.github.com/planetflash/4d9d66e924aae95f7618c03f2aabd4a3

app.run(['$rootScope', '$window', function($rootScope, $window){ 
$rootScope.$on('$locationChangeSuccess', function(event){ 
    $rootScope.absurl = $window.location.href; 
}); 

<svg><use xlink:href="{{absurl+'#svgvID'}}"></use></svg>