gpt4 book ai didi

javascript - Angular.js 在指令中更新 SVG 模板

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:44:52 26 4
gpt4 key购买 nike

前一段时间我问过“Angular.js rendering SVG templates in directives”,在那里我用 SVG 节点替换了在渲染模板时 Angular 生成的 DOM 节点。我得到了为我回答的回复,但我意识到我丢失了 Angular 所有数据绑定(bind)。

参见 Plunkr(点击更新):http://plnkr.co/edit/HjOpqc?p=preview

如何用 SVG 节点替换这些 DOM 节点,并保持 Angular 绑定(bind)不变?我尝试使用 $compile 使其工作(就像我对常规 html 所做的那样),但它就是不工作。

代码:

var svgNS = 'http://www.w3.org/2000/svg';
app.directive('path', ngSvg('path'));
app.directive('g', ngSvg('g'));

function ngSvg(type) {
return function($timeout, $compile) {
return {
restrict: 'E',
link: function(scope, el, attr) {
//skip nodes if they are already svg
if (el[0].namespaceURI === svgNS) {
return;
}

// I would expect the chunk of code below to work,
// but it does not with ng-repeat

// var newAttr = {};
// _.each(el[0].attributes, function(at) {
// newAttr[at.nodeName] = at.value;
// });

// var path = makeNode(type, el, newAttr);
// var parent = path.cloneNode(true);

// $compile(parent)(scope);

// var children = el.children();
// $(parent).append(children);

// $timeout(function() {
// el.replaceWith(parent);
// })


// this works for rendering, but does not update the svg elements
// when update is clicked
$timeout(function() {
var newAttr = {};
_.each(el[0].attributes, function(at) {
newAttr[at.nodeName] = at.value;
});

var path = makeNode(type, el, newAttr);
var parent = path.cloneNode(true);


var children = el.children();
$(parent).append(children);
el.replaceWith(parent);
});
}
}
}
}

/* 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(svgNS, 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;
}

最佳答案

这个问题在 Angular 1.3 中得到解决,这里是一些自定义 svg 指令的实现,具有您期望从 Angular 指令获得的行为。现在对指令声明有一个特殊要求如下templateNamespace: 'svg'

另请注意,我覆盖了一些保留属性,例如 xheight关于<rect/> .要保留对这些的更多控制,您可以利用 ng-attr因此 '<rect ng-attr-width="{{ ngWidth }}" />

JSFiddle Link

这是一个自定义 <rect/><circle/>

app.directive('ngRect', [function () {
return {
templateNamespace: 'svg',
replace: true,
template: '<rect ng-attr-width="{{ ngWidth }}" ng-attr-height="{{ ngHeight }}" ng-attr-x="{{ ngX }}" ng-attr-y="{{ ngY }}" ng-click="ngRectClick()"/>',
scope: {
'ngHeight': '=',
'ngWidth': '='
},
link: function (scope, elem, attrs) {
scope.ngRectClick = function() {
console.log(elem);
}
}
}
}]);

app.directive('ngCircle', [function () {
return {
templateNamespace: 'svg',
replace: true,
template: '<circle ng-attr-cx="{{ ngCx }}" ng-attr-cy="{{ ngCy }}" ng-attr-r="{{ ngR }}" ng-attr-fill="{{ ngFill }}" ng-click="ngCircleClick()"/>',
scope: {
'ngCx': '=',
'ngCy': '=',
'ngR': '=',
'ngFill': '='
},
link: function (scope, elem, attrs) {
scope.ngCircleClick = function() {
console.log(elem);
}
}
}
}]);

关于javascript - Angular.js 在指令中更新 SVG 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20504438/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com