I'm attempting to bind SVG attributes using AngularJS. I have the following code for a resize handle of a shape:
// S handle.
var s_handle = d3.select(document.createElementNS("http://www.w3.org/2000/svg", "rect"))
.attr("id", "s-resize")
.attr("x", "{{(objects['" + id + "'].w - (scope.dragHandle.width / 2))}}")
.attr("y", "{{(objects['" + id + "'].h - (scope.dragHandle.width / 2))}}")
.attr(scope.dragHandle)
.attr("cursor", "s-resize")
.call(sresize);
$compile(s_handle.node())(scope);
element.append(s_handle);
When I run this code, I get the following error:
Error: Invalid value for <rect> attribute x="{{(objects['9b320170-6365-4f40-801d-a7a5c6b936f9'].w - (scope.dragHandle.width / 2))}}" d3.min.js:1
Error: Invalid value for <rect> attribute y="{{(objects['9b320170-6365-4f40-801d-a7a5c6b936f9'].h - (scope.dragHandle.width / 2))}}" d3.min.js:1
I tried removing the append step to isolate the issue - and it looks like the issue actually happens when I set the x and y attributes, even before the Angular compile stage.
Note that I have this method working with another SVG object using the transform attribute, which natively accepts a string.
Has anyone run into this problem before? Are there any solutions? Thank you.
Edit: Been stepping through and it looks like $compile` isn't actually changing the element at all. Could this be because the element is invalid?
Looks like this was related to this issue: https://github.com/angular/angular.js/pull/2061
It was solved in that issue as well.
SVG elements use an XML-based schema, and are namespaced, and as such have validation rules. Certain attributes can't take an Angular interpolated directive because they expect a numeric value, and the browser validates this before Angular ever has a chance to catch it (even if the element is created and not appended to the DOM yet).
If anyone runs into this issue, hopefully this answer will help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With