我有兴趣通过组合包装在 Angular.js 指令中的可重用图形元素来构建复合 SVG。例如我可能有:
<div ng-app="svgApp">
<canvas>
<drawing ng-repeat="i in [1,2,3]" cy="{{i * 40}}"></drawing>
</canvas>
</div>
我在哪里定义以下指令:
.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 元素似乎没有被正确地嵌入。在另一个 StackOverflow 问题中似乎有一个线索,这主要是因为 SVG 节点没有在 Angular.js 中正确创建。
在进一步探索之后,我发现了这个解决方案,它涉及使用辅助函数将相关的 DOM 元素替换为正确创建的 SVG 节点,例如:
.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 的本地,直到它被修复。
我的问题是以下是否是一个合理的解决方法:
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 元素指令对我有效吗?