当前位置: 首页 > 面试题库 >

在AngularJS指令中渲染SVG模板

呼延聪
2023-03-14
问题内容

我正在使用SVG和angular.js进行大型项目,并且需要对svg指令模板的坚实支持。不幸的是,当angular渲染模板时,它将创建DOM节点,而不是SVG节点。我当前的解决方法是使用jquery.svg自己管理创建和删除节点,但是它受到限制。示例:http://plnkr.co/edit/Xk8wM3?p
= preview

我想让指令element成为实际的svg元素,而不是一些没有任何实际作用的人造DOM元素。这将使我有效地使用ng-repeat和angular过滤器。

这是需要修复的插件:http
://plnkr.co/edit/BPvGjf?p=preview

html

<svg>
  <!--woot this one works-->
  <shape d="M0,0L250,0L250,250L0,250z" fill="green"></shape>

  <!--nesting directives doesn't work-->
  <group>
    <shape d="M0,0L150,0L150,150L0,150z" fill="red"></shape>
    <shape d="M0,0L100,0L100,100L0,100z" fill="orange"></shape>
  </group>

  <!--ng repeat doesn't work-->
  <shape d="{{square.path}}" fill="{{square.color}}" ng-repeat="square in squares | orderBy:'order'"></shape>
</svg>

javascript

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.squares = [{
    path: "M0,0L50,0L50,50L0,50z",
    color: 'blue',
    order: 2
  }, {
    path: "M0,0L75,0L75,75L0,75z",
    color: 'purple',
    order: 1
  }];
});

app.directive('group', function($compile) {
  return {
    restrict: 'E',
    transclude: true,
    compile: function(tElement, tAttr, transclude) {
      var path = makeNode('g', tElement, tAttr);

      tElement.append(path.cloneNode(true));

      return function(scope, element) {
        transclude(scope, function(clone, innerScope) {
          element.append($compile(clone)(innerScope));
        })
      }
    }
  }
});

app.directive('shape', function() {
  return {
    restrict: 'E',
    compile: function(tElement, tAttr) {
      var path = makeNode('path', tElement, tAttr);

      tElement.replaceWith(path.cloneNode(true));

      return function(scope, element) {

      }
    }
  }
})

/* Create a shape node with the given settings. */
function makeNode(name, element, settings) {
  var svg = $(element).parents('svg')[0];
  var parent = $(element).parent()[0];
  var factory = $('#factory')[0] || $('body').append('<svg id="factory"></svg>').find('#factory')[0];
  var ns = 'http://www.w3.org/2000/svg';

  // I've tried using the factory here to create the node then clone
  // it into the new svg, but since angular nodes are created child-first, it didn't work

  var node = parent.ownerDocument.createElementNS(ns, name);
  for (var attribute in settings) {
    var value = settings[attribute];
    if (value !== null && value !== null && !attribute.match(/\$/) &&
      (typeof value !== 'string' || value !== '')) {
      node.setAttribute(attribute, value);
    }
  }
  parent.appendChild(node);
  return node;
}

问题答案:

我已经分叉并更新了您的拨弄器,使其在这里工作。有时,当相关节点通过角度从文档中分离出来进行处理时,您的函数“
makeNode”会引发错误。使用0毫秒的超时可以使执行延迟到足以使父节点可用的程度。另外,我正在使用链接函数执行所有操作,因为编译函数每个ng-
repeat只执行一次,但是我们需要重复多次。您可以在Angular
Directive页面上的“
Compile和Link之间的区别”部分下详细了解编译和链接函数之间的区别。

以下是相关代码:

/* Create a shape node with the given settings. */
function makeNode(name, element, settings) {
  var ns = 'http://www.w3.org/2000/svg';
  var node = document.createElementNS(ns, name);
  for (var attribute in settings) {
    var value = settings[attribute];
    if (value !== null && value !== null && !attribute.match(/\$/) &&
      (typeof value !== 'string' || value !== '')) {
      node.setAttribute(attribute, value);
    }
  }
  return node;
}


 类似资料:
  • 问题内容: 我创建了一个生成Twitter按钮的指令。由于这些按钮上的作用域变量可能会更改,因此我需要在按钮发生时重新构建它。目前,我正在使用jQuery 链接元素并重建按钮。 有没有办法让指令完全重新呈现模板呢? 问题答案: 这是一个可重用的指令,您可以使用它在发送事件时重建被包含的内容: 这是一个jsFiddle演示其工作原理:http : //jsfiddle.net/robianmcd/Z

  • 问题内容: 由于存在题外问题,这是一种重写: 我写了一个下拉菜单指令。我将指令两次用作工作流。第一个下拉菜单通过更改操作触发第二个模型的刷新。尽管模型正确更新,但视图未正确更新。在下拉菜单中多次选择项目时,即使角度模型的console.log()正确,第二个下拉菜单也会显示带有新项目的旧项目。 该视图具有无限递归。使用具有ng / template的ID的ng-include可以自我递归: 我最初

  • 我想用svg画一个模糊的圆,但是用一些更高的stdDeviation值,它会被裁剪。 我尝试了几个属性,比如“fegaussianblur”标签上的“edgemode”,或者“circle”和“filter”标签上的“width=”150%“和”height=“150%”,但没有任何帮助。 有什么想法吗?

  • SVGRenderer被用于使用SVG来渲染几何数据,所产生的矢量图形在以下几个方面十分有用: 动画标志(logo)或者图标(icon) 可交互的2D或3D图表或图形 交互式地图 复杂的或包含动画的用户界面 SVGRenderer具有很多优势。它产生清晰并且锐利的图像输出,它和实际视口分辨率无关。 SVG元素可以通过CSS来控制样式;并且由于它可以添加诸如标题或者描述文字之类的元数据(对于搜索引擎

  • 6.1 渲染模板 一旦你拥有一个模版文件,你可以通过给一个map来给它传递数据。 map是一个变量及赋予的值的集合,模板使用它来得到变量的值,或者对于块标签求值。 它的渲染函数有一个可选的变量键值对map 通过 ctx.Render() 方法来渲染模板,例如: func (r *Render) Serve(ctx *faygo.Context) error { return ctx.Ren

  • 问题内容: 我有一个用于渲染表单元格的指令(请参阅我在这里如何编译它的方法,基本上是在[Angular.js指令模板中使用父/继承作用域中的变量,现在在两个s中使用,一个用于行,一个对于列,所以基本上 包含50行和8列的列,对(渲染)性能产生了很大的影响(无论如何还是很明显的)。 所以我一直在寻找一种改善它的方法。首先,我尝试摆脱对列的内部重复,创建一个在内部对列进行迭代的方法,找到它们的模板,创