AngularJS ng-href 和 svg xlink
Posted
技术标签:
【中文标题】AngularJS ng-href 和 svg xlink【英文标题】:AngularJS ng-href and svg xlink 【发布时间】:2013-03-31 12:02:51 【问题描述】:我想要一些关于使用带有 angular 的 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图像将无法呈现。
任何关于如何最好地处理 xml 命名空间/svg 和 angular 的建议将不胜感激。
【问题讨论】:
我没有找到您问题的答案,但感谢您发布 Plunker。我将它用于我自己的角度 SVG 绑定。 【参考方案1】:你可以使用ng-attr-<some attribute>
ng-attr-xlink:href="xxx"
为我工作。
请注意,您还需要一个空的xlink:href=""
作为初始值。 ——德里克·许
【讨论】:
这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方发表评论 - 您可以随时评论自己的帖子,一旦您有足够的reputation,您就可以comment on any post。 @Siddharth,实际上确实如此。问题不仅仅是关于自定义指令。事实上,@Leon 想要一些关于使用带有 angular 的 xml 命名空间属性的输入,以及关于如何最好地处理 xml 命名空间 / svg 和 angular 的建议。为了解决他的问题,他甚至编写了自定义指令。我指出不需要自定义指令。 Angularjs 已经有ng-attr
为他完成这项工作。
@sheriffderek,给你angularjs ng-attr example。请注意,您还需要一个空的xlink:href=""
作为初始值。
我希望将它与
+1,这对我有用,但它非常挑剔。您在动态 ng-attr-xlink:href 之后使用了空的 xlink:href=""。另外,我认为这不适用于早期版本的 Angular。【参考方案2】:
如果您像我一样正在寻找一种将图像添加到 svg 的方法,您可以添加:
xlink:href="" ng-href=" foo "
例子:
http://jsbin.com/sigoleya/1/edit?html,js,output
我在哪里找到了解决方案:
https://github.com/angular/angular.js/issues/7697
【讨论】:
这太棒了。谢谢!【参考方案3】:我在尝试输出与模型相关的 xlink:href
值时遇到了类似的问题。基于用户在<select>
控件中选择的<option>
,我试图通过<use>
元素的xlink:href
属性显示动态SVG 图标。
我在 AngularJS 的 GitHub 问题中找到了 a thread about this。根据那里的讨论,似乎因为存在可行的解决方法,他们通过将其移至积压里程碑有效地提出了修复。
最终对我有用的是这个 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>
例如,给定icon-music
中的category.iconName
,Angular 会将xlink:href
动态设置为#icon-music
,这会在同一页面上进一步引用<svg id="icon-music">
元素。
正如其他人所指出的,关键是在调用ngHref
指令的元素上设置一个空白xlink:href=""
属性。属性顺序似乎无关紧要。使用 ng-attr-xlink:href="xxx"
(如 Derek Hsu 的回答中所述)对我不起作用。
所有这些都假设 Angular 1.3.36。
【讨论】:
非常感谢它对我有用...ng-attr-xlink:href="model" 对我不起作用..... coffeescript: 【参考方案4】:我用以下模块解决了同样的问题:
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"
ng-xlink-href="item.imageSrc"
ng- ng-
ng-cloak
/>
【讨论】:
当 xlink:href 对我不起作用时,我不得不重新阅读这篇文章。这里的关键是您需要一个假值才能开始。没有它,即使具有正确的属性,图像也不会呈现。留下此评论以帮助像我这样的其他 TL;DR 傻瓜。谢谢丹尼! @fractalspawn 欢迎您。我打算将此评论添加到答案中,然后我看到我已经将它放在 HTML 上方的评论中:-)【参考方案5】:对于由于 HTML5 模式下的 Angular/Angular UI 路由器而遇到此问题的任何其他人,我想出了一个简单的修复方法,使 svg sprite 图标能够与它们的 xlink:href 属性和标签一起使用。
要点在这里: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>
【讨论】:
【参考方案6】:我在使用 Ajax 将 svg spritesheet 加载到页面上时遇到了这个问题。如果在加载 spritesheet 之前我在页面上有一个,它将失败并且一旦 spritesheet 可用就不会解决。加载 spritesheet 后添加到 dom 的任何内容都可以。我不得不推迟将项目放入 dom 直到 spritesheet 完成加载。
这只影响了 ios。所有其他浏览器都不关心顺序。
【讨论】:
【参考方案7】:这花费了我比我想要的更多的时间。大约 20-30 分钟。
如果我理解正确,图像元素上的任何失败加载都会使该元素在未来变得无用。我相信这与@GeekyMonkey 所说的类似。如果角度绑定系统最初将 xlink:href 设置为 null,则 Image 元素将不再起作用,即使我们将来有有效值也是如此。
这是解决方案,请注意我是如何使用 ng-if 指令将图像元素包裹在 g 元素中的。这确保我们仅在正确的值可用时才绑定图像。
<g ng-if="vm.svgMap.background != null">
<image
ng-attr-xlink:href="vm.svgMap.background.image | trusted"
ng-attr-
ng-attr-
xlink:href=""
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);
;
;
());
【讨论】:
以上是关于AngularJS ng-href 和 svg xlink的主要内容,如果未能解决你的问题,请参考以下文章
AngularJS进阶(三十二)书海拾贝之特殊的ng-src和ng-href
AngularJS:如何通过 ng-href 将多个参数传递给控制器?
使用 CSS 或 AngularJS 的 SVG 路径元素悬停缩放