AngularJS:在指令Transcluding SVG元素 [英] AngularJS : Transcluding SVG elements in directives

查看:139
本文介绍了AngularJS:在指令Transcluding SVG元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我感兴趣的是通过组合包装Angular.js指令内可重复使用的图形元素构建一个复合SVG。比如我可能有:

I'm interested in building a composite SVG by composing reusable graphical elements wrapped inside of Angular.js directives. For instance I might have:

<div ng-app="svgApp">
  <canvas>
    <drawing ng-repeat="i in [1,2,3]" cy="{{i * 40}}"></drawing>
  </canvas>
</div>

在这里我定义下列指令:

where I am defining the following directives:

  .directive('canvas', function () {
    return {
      template: '<svg height=200 width=100 ng-transclude></svg>',
      restrict: 'E',
      replace: true,
      transclude: true
    };
  })

  .directive('drawing', function () {
    return {
      template: '<circle cx=50 r=15></circle>',
      restrict: 'E',
      replace: true
    };
  })

的问题是,在SVG元素似乎没有得到正确transcluded。一条线索似乎是<一个href=\"http://stackoverflow.com/questions/13641105/including-svg-template-in-angularjs-directive\">here,在另一个计算器的问题,这主要是因为SVG节点内不正确Angular.js创建。

The problem is that the SVG elements do not appear to get transcluded properly. A clue seems to be here, in another StackOverflow question that this is mostly because SVG nodes are not created properly within Angular.js.

闲逛进一步后,我发现此解决方案,其中包括使用一个辅助函数,以取代正确创建SVG节点相关的DOM元素,一拉:

After poking around further, I found this solution, which involves using a helper function to replace the relevant DOM elements with properly created SVG nodes, a la:

  .value('createSVGNode', function(name, element, settings) {
      var namespace = 'http://www.w3.org/2000/svg';
      var node = document.createElementNS(namespace, name);
      for (var attribute in settings) {
        var value = settings[attribute];
        if (value !== null && !attribute.match(/\$/) && (typeof value !== 'string' || value !== '')) {
            node.setAttribute(attribute, value);
        }
      }
      return node;
  });

不过,它似乎不可取,我需要到处使用这一点,我想解决方法本地保持的bug越好,直到它是固定的。

However, it seemed undesirable that I would need to use this everywhere, and I wanted to keep the workaround as local to the bug as possible, until it was fixed.

我的问题是下面是否是一个合理的解决方法:

My question is whether the following would be a reasonable workaround:

angular.forEach(['circle', ...], function (svgElem) {

  svgModule

    .directive(svgElem, function (createSVGNode) {
      return {
        restrict: 'E',
        link: function(scope, element, attrs) {
          var node = createSVGNode(svgElem, element, attrs);
          angular.element(node).append(element[0].childNodes);
          element.replaceWith(node);
        }
      };
    });

});

和这部作品在 Plunker

有效期是我重新认识了现有的SVG元素的指令以这种方式?

Is it valid for me to redefine existing SVG element directives in this way?

推荐答案

以上是一个可行的方法,如果你不能移动你的code高达AngularJS 1.3积极发展尖端位置不同的transcluding元素的问题命名空间(如SVG或MATHML)是解决

The above is a possible approach if you cannot move your code up to the active development tip of AngularJS 1.3 where the issue of transcluding elements of a different namespace (such as SVG or MathML) is resolved.

链接的 Plunker 演示了如何更新code。与此修复程序。关键是增加在指令中定义对象的新templateNamespace键的

The linked Plunker demonstrates how to update your code with the fix. The key is the addition of a new "templateNamespace" key in the directive definition object:

  .directive('svgInternal', function () {
    return {
      templateNamespace: 'svg',
      template: '<g><rect height="25" width="25" /><text x="30" y="20">Hello, World</text></g>',
      restrict: 'E',
      replace: true
    };
  })

其中,下面的标记演示了SVG型指令使用

where the following markup demonstrates the SVG-type directive in use:

  <svg height="30">
    <svg-internal></svg-internal>
  </svg>

修改:类型改为templateNamespace,因为1.3.beta.19

Edit: "type" was changed to "templateNamespace" since 1.3.beta.19.

这篇关于AngularJS:在指令Transcluding SVG元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆