Brendan Hill Brendan Hill - 5 months ago 38
AngularJS Question

How to get AngularJS to fill initial tag value in svg template?

I'm trying to get an AngularJS directive to set various properties in an svg tag.

.directive("cartesianPlane", function() {
return {
restrict: "E",
scope: { },
templateUrl: "shared/cartesianPlane/cartesianPlaneView.html",
controller: function($scope) {
$scope.viewBox = {
x : -20,
y : -20,
width : 40,
height : 40,

value : function() {
return this.x + ' ' + this.y + ' ' + this.width + ' ' + this.height;
link: function($scope, $elem) {
// Then adjust for aspect ratio
var aspectRatio = $elem.height() / elem.width();
$scope.viewBox.height = $scope.viewBox.width * aspectRatio;

<!-- cartesianPlaneView.html -->

<svg width='100%' height='100%' viewBox='{{viewBox.value()}}' style='position:relative; top:0px; left:0px; float:left;'>
<line class='axis' x1='{{viewBox.x}}' y1='0' x2='{{viewBox.x + viewBox.width}}' y2='0'></line>
<line class='axis' x1='0' y1='{{viewBox.y}}' x2='0' y2='{{viewBox.y + viewBox.height}}'></line>

There are two problems with this method:

1) AngularJS seems to render the tag from the templateUrl without inserting the values initially. Therefore the browser complains:

Error: Invalid value for <svg> attribute viewBox="{{viewBox.value()}}"
Error: Invalid value for <line> attribute y1="{{viewBox.y}}"
Error: Invalid value for <line> attribute y2="{{viewBox.y + viewBox.height}}"
Error: Invalid value for <line> attribute x1="{{viewBox.x}}"
Error: Invalid value for <line> attribute x2="{{viewBox.x + viewBox.width}}"

I would have thought that when the template was rendered, the initial values from $scope would be inserted immediately? Instead the template {{}} tags are going in as is.

2) The $elem parameter to the link function doesn't have width() and height() properties. When are these available and how can I compute & set the aspectRatio when they are?

Error: TypeError: $elem.height() is not a function


I believe for problem #1 you'll want to use ng-attr. So, in your directive, you'll use ng-attr-viewBox, ng-attr-x, etc...

As for your second problem, .height() should be available there and should be provided by JQLite