Ответ 1
Вы можете использовать ng-attr-<some attribute>
ng-attr-xlink:href="{{xxx}}"
работает для меня.
Обратите внимание, что вам также нужно пустое xlink:href=""
как начальное значение. - Дерек Хсу
Мне нужен вход для использования атрибутов с именами xml с именами angular.
Проблема заключается в том, что angular содержит пару директив для обработки атрибутов записи, таких как href и src, когда angular проанализировал выражения (иначе браузер попытается загрузить {{mymodel.myimage}}
в качестве URL-адреса)
https://github.com/angular/angular.js/blob/master/src/ng/directive/booleanAttrs.js#L329
Проблема, с которой я сталкиваюсь, заключается в том, что я использую angular для вывода svg вместе с D3, и поскольку angular не имеет способа вывода xlink:href
, я застрял.
Я создал настраиваемую директиву, которая выводит 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);
});
}
};
});
Полная демонстрация: http://plnkr.co/edit/cMhGRh
Но кажется, что если я не добавлю вручную xlink: href к элементу, изображение svg не будет отображаться.
Приветствуются любые предложения о том, как наилучшим образом обрабатывать пространства имен xml/svg вместе с angular.
Вы можете использовать ng-attr-<some attribute>
ng-attr-xlink:href="{{xxx}}"
работает для меня.
Обратите внимание, что вам также нужно пустое xlink:href=""
как начальное значение. - Дерек Хсу
Если, как и я, вы ищете способ добавления изображений в svg, вы можете сделать это:
xlink:href="" ng-href="{{ foo }}"
Пример:
http://jsbin.com/sigoleya/1/edit?html,js,output
Где я нашел решение:
У меня возникла аналогичная проблема при попытке вывода значения для xlink:href
, привязанного к модели. Исходя из выбранного пользователем элемента <option>
в элементе управления <select>
, я пытался показать динамический значок SVG с помощью атрибута xlink:href
элемента <use>
.
Я нашел поток об этом в вопросах GitHub для AngularJS. Основываясь на обсуждении там, похоже, что, поскольку существует жизнеспособное обходное решение, они эффективно внесли исправление, переместив его на веху в Backlog.
То, что в конечном итоге сработало для меня, было вдохновлено этим JSBin:
http://jsbin.com/sigoleya/1/edit?html,js,output
Вот код, который я использовал в моем шаблоне:
<svg class="icon" data-ng-class="category.iconName">
<use xlink:href="" data-ng-href="{{'#' + category.iconName}}">
</svg>
Учитывая category.iconName
of icon-music
, например, Angular динамически устанавливает xlink:href
на #icon-music
, который ссылается на элемент <svg id="icon-music">
далее на той же странице.
Как отмечали другие, какой ключ устанавливает пустой атрибут xlink:href=""
в элементе, где вы вызываете директиву ngHref
. Порядок атрибутов не имеет значения. Использование ng-attr-xlink:href="{{xxx}}"
(как упоминалось в ответе Дерека Хсу) не сработало для меня.
Все это предполагает Angular 1.3.36.
Я решил ту же проблему со следующими модулями:
Модуль для 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);
});
}
};
});
});
Модуль для обнаружения 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
/>
Для всех, у кого есть эта проблема из-за Angular/Angular UI Router в режиме HTML5, я придумал прямое исправление, позволяющее значкам svg sprite работать со своим атрибутом xlink: href и тегом.
Gist здесь: 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>
Я столкнулся с этой проблемой, когда я использовал Ajax для загрузки svg spritesheet на страницу. Если бы у меня была страница на странице до того, как был загружен спрайт, она потерпит неудачу и не будет разрешаться после того, как спрайт будет доступен. Любое добавление в дом после загрузки спрайта было прекрасным. Мне пришлось откладывать предметы в доме до тех пор, пока после того, как спрайт закончил загрузку.
Это повлияло только на IOS. Все остальные браузеры не заботились о заказе.
Мне потребовалось больше времени, чем хотелось бы. Около 20-30 минут.
Если я правильно понимаю, любая неудачная загрузка элемента изображения будет сделать этот элемент бесполезным в будущем. Я верю, что это что-то похожее @GeekyMonkey говорит. Если система привязки angular установила xlink: href изначально имеет значение null, элемент изображения больше не будет работать, даже если у нас есть действительное значение в будущем.
Вот решение, обратите внимание, как я обернул элемент изображения внутри элемента g, используя директиву ng-if. Это гарантирует, что мы будем привязываться к изображению только тогда, когда доступно правильное значение.
<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>
Как говорят другие, порядок атрибутов также важен. Чтобы гарантировать, что angularJS позволяет нам связывать элемент изображения, мы также должны будем доверять этому ресурсу, я сделал это через фильтр (это тот, который указан в атрибуте xlink: href):
(function() {
'use strict';
angular.module('myTool').filter('trusted', TrustedFilter);
function TrustedFilter($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
};
}());