AngularJS ng-href i svg xlink


Chciałbym uzyskać pewne informacje o użyciu atrybutów przestrzeni nazw XML z kątowym.
Problem polega na tym, że angular zawiera kilka dyrektyw do obsługi atrybutów postów, takich jak href i src, podczas analizowanych wyrażeń kątowych (w przeciwnym razie przeglądarka spróbuje załadować
{{mymodel.myimage}}
jako adres URL)
https://github.com/angular/ang ... 3L329
https://github.com/angular/ang ... 3L329
Problem polega na tym, że używam angular do wypisywania svg wraz z D3, a ponieważ angular nie ma możliwości wypisania
xlink: href
utknąłem.
Stworzyłem niestandardową dyrektywę, która wyświetla 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);
});
}
};
});

Pełna wersja demo:

http://plnkr.co/edit/cMhGRh
http://plnkr.co/edit/cMhGRh
Ale wygląda na to, że jeśli nie dodam ręcznie xlink: href do elementu, obraz svg nie zostanie wyświetlony.
Wszelkie sugestie, jak najlepiej obsługiwać przestrzenie nazw xml/svg wraz z angularem byłyby bardzo mile widziane.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz użyć
ng-attr- & < some attribute & >
ng-attr-xlink: href = "{{xxx}}"
mi pasuje.
Pamiętaj, że jako wartość początkową potrzebujesz również pustej wartości
xlink: href = ""
. - Derek Hsu
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli tak jak ja szukasz sposobu na dodanie obrazów do svg, możesz to zrobić, dodając:
xlink:href="" ng-href="{{ foo }}"

Przykład:
http://jsbin.com/sigoleya/1/edit?html,js,output
http://jsbin.com/sigoleya/1/edit?html,js,output
Gdzie znalazłem rozwiązanie:
https://github.com/angular/angular.js/issues/7697
https://github.com/angular/angular.js/issues/7697
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Pobiegłem do podobnego problemu podczas próby wyświetlania wartości dla Xlink: Href , przywiązany do modelu. W oparciu o wybrany użytkownik
& LT; Option & GT;
W elemencie sterowania
& LT; Wybór & GT;
Próbowałem pokazać ikonę dynamiczną SVG przez
Atrybut XLink: HREF
Element
& LT; Użyj
.
znalazłem

wątek o tym
https://github.com/angular/angular.js/issues/7697
Zobacz wydanie AngularJS GitHub. Na podstawie tamtej dyskusji wydaje się, że skoro istnieje realne obejście, skutecznie wprowadzili poprawkę, przenosząc ją do zaległości.
To, co ostatecznie zadziałało dla mnie, zostało zainspirowane tym JSBin:
http://jsbin.com/sigoleya/1/edit?html,js,output
http://jsbin.com/sigoleya/1/edit?html,js,output
Oto kod, którego użyłem w moim szablonie:
<svg class="icon" data-ng-class="category.iconName">
<use xlink:href="" data-ng-href="{{'#' + category.iconName}}">
</svg>

Na przykład, jeśli
category.iconName
jest ustawiona z
icon-music
, to Angular dynamicznie ustawi
xlink: href
na
# icon- music
, który prowadzi do elementu
& < svg id = "icon-music" & >
w dalszej części tej samej strony.
W drugim, drugi, kluczowy punkt jest zainstalowany pusty atrybut XLink: Href = "" dla elementu, w którym dzwonisz do Dyrektywa NGREF . Kolejność atrybutów, najwyraźniej nie ma znaczenia. Korzystanie z
NG-attr-Xlink: Href = "{XXX}}"
(jak wspomniano w odpowiedzi Derek HSU) nie działał dla mnie.
Wszystko to zakłada Angular 1.3.36.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Rozwiązałem ten sam problem z następującymi modułami:
Moduł dla 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);
});
}
};
});
});

Moduł wykrywania 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
/>
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dla tych, którzy nadal mają ten problem z powodu routera Angular/Angular UI w trybie HTML5, wymyśliłem prostą poprawkę, aby umożliwić ikonom sprite svg działanie z ich atrybutem i tagiem xlink: href.
Istota jest tutaj:

https://gist.github.com/planet ... bd4a3
https://gist.github.com/planet ... bd4a3
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>
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Napotkałem ten problem, gdy używałem Ajax do załadowania arkusza sprite svg na stronę. Gdybym miał na stronie przed załadowaniem arkusza sprite, to nie powiodło się i nie rozwiązałoby się, gdy arkusz sprite byłby dostępny. Wszystko dodane do domeny po załadowaniu arkuszy sprite'ów było w porządku. Musiałem odłożyć umieszczanie elementów w dom do czasu zakończenia ładowania arkusza sprite.
Dotyczyło to tylko iOS. Wszystkie inne przeglądarki nie dbały o porządek.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zajęło mi to więcej czasu, niż bym chciał. Około 20-30 minut.
Jeśli dobrze rozumiem, nieudane ładowanie elementu obrazu

uczyni ten element bezużyteczny w przyszłości
... Myślę, że jest to coś podobnego, mówi @GeekyMonkey. Jeśli system wiązań kątowych początkowo ustawił xlink: href na null, element obrazu nie będzie już działał, nawet jeśli w przyszłości będziemy mieć prawidłową wartość.
Oto rozwiązanie: Zwróć uwagę, jak zawinąłem element image wewnątrz elementu g za pomocą dyrektywy ng-if. Zapewnia to, że łączymy się z obrazem tylko wtedy, gdy dostępna jest prawidłowa wartość.
<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>

Jak powiedzieli inni, kolejność atrybutów jest również ważna. Aby upewnić się, że angularJS pozwala nam powiązać element obrazu, musimy również zaufać temu zasobowi, zrobiłem to przez filtr (jest w atrybucie xlink: href):
(function() {
'use strict'; angular.module('myTool').filter('trusted', TrustedFilter); function TrustedFilter($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
};
}());

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się