![](/img/trans.png)
[英]Angular.js caching $compiled templates / rendering performance of directives inside ng-repeat
[英]Angular.js updating SVG templates in directives
前一段時間我問過“ Angular.js在指令中渲染SVG模板 ”,我用SVG節點替換渲染模板時角度所產生的DOM節點。 我得到了一個響應它,但我意識到我丟失了所有的數據綁定。
請參閱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'
另請注意,我正在覆蓋一些保留屬性,例如x
和height
( <rect/>
。 為了保持對這些控制的更多控制,你可以利用ng-attr
這樣的'<rect ng-attr-width="{{ ngWidth }}" />
這是一個自定義的<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);
}
}
}
}]);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.