角度付きのxml名前空間付き属性の使用に関する入力をお願いします。
問題はangularには、angularが式を解析したときにhrefやsrcなどの属性の書き込みを処理するためのいくつかのディレクティブが付属しています(そうでない場合、ブラウザは_{{mymodel.myimage}}
_をURLとしてロード)
https://github.com/angular/angular.js/blob/master/src/ng/directive/booleanAttrs.js#L329
私が直面している問題は、angularを使用してD3と一緒にsvgを出力していることです。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画像がレンダリングされないようです。
angularと一緒にxml名前空間/ svgを最適に処理する方法についての提案は、大歓迎です。
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>
_に基づいて、_xlink:href
_要素の_<use>
_属性を介して動的SVGアイコンを表示しようとしました。
AngularJSのGitHubの問題で これに関するスレッド を見つけました。そこでの議論に基づいて、実行可能な回避策が存在するため、バックログマイルストーンに移動することで修正を効果的にまとめたようです。
最終的に私のために機能したのは、この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
_の_icon-music
_を指定すると、Angularは_xlink:href
_を_#icon-music
_に動的に設定し、_<svg id="icon-music">
_を参照します同じページのさらに上の要素。
他の人が指摘したように、重要なのは、ngHref
ディレクティブを呼び出す要素に空の_xlink:href=""
_属性を設定することです。属性の順序は重要ではないようです。 _ng-attr-xlink:href="{{xxx}}"
_(Derek Hsuの回答で述べたように)を使用してもうまくいきませんでした。
これはすべて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
/>
HTML5モードのAngular/Angular UIルーターが原因でこの問題が発生している他の人のために、svgスプライトアイコンがxlink:href属性とタグで機能するようにする簡単な修正を思いつきました。
Gist is here: 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>
これには、思ったよりも時間がかかりました。約20〜30分。
私が正しく理解していれば、画像要素の読み込みに失敗するとその要素は今後役に立たなくなりますになります。 @GeekyMonkeyが言っているのと同じようなことだと思います。 angularバインディングシステムが最初にxlink:hrefをnullに設定した場合、将来有効な値があったとしても、Image要素は機能しなくなります。
これが解決策です。ng-ifディレクティブを使用して、image要素をg要素内にラップしたことに注意してください。これにより、正しい値が使用可能な場合にのみイメージにバインドします。
<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);
};
};
}());
私はAjaxを使用してsvgスプライトシートをページにロードしていたときにこの問題に遭遇しました。スプライトシートがロードされる前にページ上にaがあった場合、それは失敗し、スプライトシートが使用可能になると解決しません。スプライトシートが読み込まれた後にdomに追加されたものは問題ありませんでした。スプライトシートの読み込みが完了するまで、アイテムをdomに入れるのを遅らせなければなりませんでした。
これはIOSにのみ影響しました。他のすべてのブラウザは順序を気にしませんでした。