我已经创建了一个用于在<svg>
元素中渲染矩形的指令。
app.directive('drRect', ['$compile', function ($compile) {
return {
restrict: 'E',
link: function (scope, element, attrs) {
// #makeNode simply creates a DOM node using
// `document.createElementNS` so that it can be appended to an SVG
// element. It also assigns any attributes on the directive. See the
// linked fiddle for definition.
var shape = makeNode('rect', element, attrs);
var elementShape = angular.element(shape);
element.replaceWith(shape);
// Not sure what this is doing. It comes from: http://goo.gl/ZoYpQv
attrs.$observe('value', function (value) {
scope['value'] = parseInt(value, 10);
$compile(shape)(scope);
});
}
};
}]);
我在<svg>
标记内使用此指令来渲染矩形。我还有一个输入列表,您希望这些输入绑定到每个x
的{{1}}属性。但是,更改<rect>
的值不会更改矩形上的相应属性(x
代表矩形距svg左侧的距离)。您可以测试此系统with this JSFiddle。
x
我怀疑当我替换<div ng-controller="MainController">
<svg height="200" width="200">
<dr-rect ng-repeat="shape in shapes" fill="{{shape.fill}}" height="{{shape.height}}" width="{{shape.width}}" x="{{shape.x}}" y="{{shape.y}}"></dr-rect>
</svg>
<ul>
<li ng-repeat="shape in shapes">
<input type="text" ng-model="shape.x"/> {{shape.x}}
</li>
</ul>
</div>
函数中的元素时,绑定会丢失。
link
您可以看到我期望in this other JSFiddle的行为类型,其中更改输入中的值确实会更改指令中的值。
如何使用SVG元素获得相同的行为?
编辑:我让它以一种黑客的方式工作。基本上我可以element.replaceWith(shape);
模型属性,并在属性值发生变化时手动重置属性。
$watch
但这对我来说并不合适。我基本上是手动重写属性绑定系统。我不认为我应该这样做。
答案 0 :(得分:0)
您可以在没有自定义指令的情况下执行此操作。只需将元素放入ng-repeat中。在Angular可以填充rects中的值之前,您需要使用ng-attr为所有属性添加前缀以避免JS错误。请参阅更新的小提琴:http://jsfiddle.net/SWv2s/9/
<强> HTML 强>
<div ng-controller="MainController">
<svg height="200" width="200" ng-repeat="shape in shapes" ng-cloak>
<rect ng-attr-fill="{{shape.fill}}" ng-attr-height="{{shape.height}}" ng-attr-width="{{shape.width}}" ng-attr-x="{{shape.x}}" ng-attr-y="{{shape.y}}"></rect>
</svg>
<ul>
<li ng-repeat="shape in shapes">
<input type="text" ng-model="shape.x"/> {{shape.x}}
</li>
</ul>
</div>
<强>的JavaScript 强>
var myApp = angular.module('myApp', []);
myApp.controller('MainController', ['$scope', function ($scope) {
$scope.shapes = [{
x: 12,
y: 13,
height: 34,
width: 42,
fill: '#222'
}];
}]);