I'm currently working on an AngularJS directive that needs to update different attributes within an svg tag.
angular.module("complexNumbers")
.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) {
// 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>
Two issues arise with this approach:
1) It appears that when AngularJS renders the template from the templateUrl, it does not immediately insert the values. As a result, the browser raises the following errors:
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 expected the initial values from $scope to be inserted immediately upon rendering the template. However, the template {{}} tags remain as they are.
2) The $elem parameter in the link function lacks the properties width() and height(). When can these properties be accessed, and how can I compute the aspect ratio and set it appropriately?
Error: TypeError: $elem.height() is not a function