J'aimerais avoir des informations sur l'utilisation des attributs d'espaces de noms xml avec angular.
Le problème est angular est livré avec quelques directives pour gérer l'écriture d'attributs tels que href et src lorsque angular a analysé les expressions (sinon le navigateur essaiera de charge {{mymodel.myimage}}
comme une URL)
https://github.com/angular/angular.js/blob/master/src/ng/directive/booleanAttrs.js#L329
Le problème auquel je suis confronté est que j'utilise angular pour sortir svg avec D3 et depuis angular n'a pas de moyen de sortir xlink:href
J'étais coincé.
J'ai créé une directive personnalisée qui génère 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);
});
}
};
});
Démo complète: http://plnkr.co/edit/cMhGRh
Mais il semble que si je n'ajoute pas manuellement xlink: href à l'élément, l'image svg ne sera pas rendue.
Toute suggestion sur la meilleure façon de gérer les espaces de noms xml/svg avec angular serait grandement appréciée.
Vous pouvez utiliser ng-attr-<some attribute>
ng-attr-xlink:href="{{xxx}}"
travaille pour moi.
Notez que vous avez également besoin d'un xlink:href=""
comme valeur initiale. - Derek Hsu
Si, comme moi, vous cherchez un moyen d'ajouter des images au svg, vous pouvez le faire en ajoutant:
xlink:href="" ng-href="{{ foo }}"
Exemple:
http://jsbin.com/sigoleya/1/edit?html,js,output
Où j'ai trouvé la solution:
J'ai rencontré un problème similaire lors de la tentative de sortie d'une valeur pour xlink:href
qui est lié au modèle. Basé sur le choix de l'utilisateur <option>
dans un <select>
control, j'essayais d'afficher une icône SVG dynamique via le xlink:href
attribut de <use>
élément.
J'ai trouvé n fil à ce sujet dans les problèmes GitHub pour AngularJS. Sur la base de la discussion, il semble que parce qu'une solution de contournement viable existe, ils ont effectivement déposé un correctif en le déplaçant vers le jalon Backlog.
Ce qui a finalement fonctionné pour moi a été inspiré par ce JSBin:
http://jsbin.com/sigoleya/1/edit?html,js,output
Voici le code que j'ai utilisé dans mon modèle:
<svg class="icon" data-ng-class="category.iconName">
<use xlink:href="" data-ng-href="{{'#' + category.iconName}}">
</svg>
Donné un category.iconName
de icon-music
, par exemple, Angular définit le xlink:href
dynamiquement à #icon-music
, qui fait référence au <svg id="icon-music">
élément plus haut sur la même page.
Comme d'autres l'ont noté, ce qui est essentiel, c'est de mettre un _ xlink:href=""
attribut sur l'élément où vous appelez la directive ngHref
. L'ordre des attributs ne semble pas avoir d'importance. En utilisant ng-attr-xlink:href="{{xxx}}"
(comme mentionné dans la réponse de Derek Hsu) n'a pas fonctionné pour moi.
Tout cela suppose Angular 1.3.36.
J'ai résolu le même problème avec les modules suivants:
Module pour 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 pour IE détection:
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
/>
Pour toute autre personne ayant ce problème en raison du routeur d'interface utilisateur angulaire/angulaire en mode HTML5, j'ai trouvé une solution simple pour permettre aux icônes svg Sprite de fonctionner avec leur attribut xlink: href et la balise.
Gist est ici: https://Gist.github.com/planetflash/4d9d66e924aae95f7618c03f2aabd4a
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>
Cela m'a pris plus de temps que je l'aurais souhaité. Environ 20-30 minutes.
Si je comprends bien, tout échec de chargement sur l'élément image rendra cet élément inutile à l'avenir. Je pense que c'est quelque chose de similaire que dit @GeekyMonkey. Si angular a initialement défini xlink: href sur null, l'élément Image ne fonctionnera plus, même si nous avons une valeur valide à l'avenir.
Voici la solution, remarquez comment j'ai encapsulé l'élément image à l'intérieur de l'élément g, en utilisant la directive ng-if. Cela garantit que nous ne nous lierons à l'image que lorsqu'une valeur correcte est disponible.
<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>
Comme d'autres l'ont dit, l'ordre des attributs est également important. Pour nous assurer que angularJS nous permet de lier l'élément image, nous devons également faire confiance à cette ressource, je l'ai fait via le filtre (c'est celui de l'attribut xlink: href):
(function() {
'use strict';
angular.module('myTool').filter('trusted', TrustedFilter);
function TrustedFilter($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
};
}());
J'ai rencontré ce problème où j'utilisais Ajax pour charger la feuille de calcul svg sur la page. Si j'avais un sur la page avant le chargement de la feuille de sprites, il échouerait et ne se résoudrait pas une fois la feuille de sprites disponible. Tout ajout au dom après le chargement de la feuille de sprites était correct. J'ai dû retarder la mise en place des éléments dans le dom jusqu'à ce que la feuille de sprites ait fini de charger.
Cela n'a affecté que l'IOS. Tous les autres navigateurs se moquaient de la commande.