Angular.js正在更新指令中的SVG模板
Angular.js updating SVG templates in directives
不久前,我问过"Angular.js在指令中渲染SVG模板",在这里我用SVG节点替换了Angular在渲染模板时生成的DOM节点。我得到了一个回答,但我意识到我丢失了angular的所有数据绑定。
请参阅Plunkr(单击更新):http://plnkr.co/edit/HjOpqc?p=preview
如何用SVG节点替换这些DOM节点,并保持角度绑定不变?我试着使用$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'
还要注意,我正在覆盖一些保留的属性,例如,关于<rect/>
的x
和height
。为了保持对这些的更多控制,您可以利用ng-attr
作为'<rect ng-attr-width="{{ ngWidth }}" />
JSFiddle链接
这是一个自定义的<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);
}
}
}
}]);
相关文章:
- 强制模板刷新ember.js
- Dojo不解析自定义小部件的模板html中的小部件声明性
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何使用javascript从主svg对象动态创建svg视图框
- 如何更改<svg>标记为<img>用js标记
- 如何将JSON数据导入我的ejs模板
- 我的模板未被解析
- 主干模板:index.jst.eco到index.jst.ejs
- 在underscorejs模板中使用闭包
- angularjs+rails应用程序中未显示模板
- 锚点元素不't使用svg时,请打开EDGE上的href
- 以可优化的方式使用requirejs加载模板
- Jquery模板,如果xx&&如果yy
- Angular.js正在更新指令中的SVG模板
- HBS模板与咕哝博士svg精灵
- 在 AngularJS 指令中呈现 SVG 模板
- Illustrator/SVG到JavaScript工作流?(模板库?)
- 在Jade模板中包含SVG xml
- 如何让AngularJS填充svg模板中的初始标记值
- 如何通过单击 D3.js 中的 SVG 元素来添加和删除信息模板