40

我想要一些关于使用带角度的 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 的建议将不胜感激。

4

7 回答 7

61

您可以使用ng-attr-<some attribute>

ng-attr-xlink:href="{{xxx}}"为我工作。


请注意,您还需要一个空xlink:href=""作为初始值。– 德里克·许

于 2014-09-01T15:51:36.807 回答
19

如果像我一样,您正在寻找一种将图像添加到 svg 的方法,您可以添加:

xlink:href="" ng-href="{{ foo }}"

例子:

http://jsbin.com/sigoleya/1/edit?html,js,输出

我在哪里找到了解决方案:

https://github.com/angular/angular.js/issues/7697

于 2015-07-16T09:09:59.533 回答
10

在尝试输出与模型相关的值时,我遇到了类似的问题xlink:href。根据用户<option><select>控件中的选择,我试图通过元素的xlink:href属性显示动态 SVG 图标。<use>

我在 AngularJS 的 GitHub 问题中找到了一个关于此的主题。根据那里的讨论,似乎因为存在可行的解决方法,他们通过将其移至积压里程碑有效地提出了修复。

最终对我有用的是受这个 JSBin 的启发:

http://jsbin.com/sigoleya/1/edit?html,js,输出

这是我在模板中使用的代码:

<svg class="icon" data-ng-class="category.iconName">
  <use xlink:href="" data-ng-href="{{'#' + category.iconName}}">
</svg>

例如,给定 a category.iconName, Angular 将动态设置为,它在同一页面上进一步引用该元素。icon-musicxlink:href#icon-music<svg id="icon-music">

正如其他人所指出的,关键是xlink:href=""在调用ngHref指令的元素上设置空白属性。属性顺序似乎无关紧要。使用ng-attr-xlink:href="{{xxx}}"(如 Derek Hsu 的回答中所述)对我不起作用。

所有这些都假设 Angular 1.3.36。

于 2015-01-10T21:16:16.987 回答
6

我用以下模块解决了同样的问题:

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
    />
于 2013-06-07T15:49:50.480 回答
2

对于由于 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>
于 2016-07-07T11:13:37.383 回答
0

我在使用 Ajax 将 svg spritesheet 加载到页面上时遇到了这个问题。如果我在加载 spritesheet 之前在页面上有一个,它会失败并且一旦 spritesheet 可用就不会解析。加载 spritesheet 后添加到 dom 中的任何内容都可以。我不得不推迟将项目放入 dom 直到 spritesheet 完成加载之后。

这只会影响 IOS。所有其他浏览器都不关心订单。

于 2015-07-21T14:11:26.323 回答
0

这花费了我比我想要的更多的时间。大约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-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);
        };
    };
}());
于 2015-11-15T16:40:27.050 回答