In my attempts at having angularjs and d3js working together smoothly, I run in trouble when I try to watch an attribute value right within a directive. Let me illustrate with those two simple directives:
.directive('attr1', function($compile) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var attr3val = 0;
d3.select(element[0])
.attr('attr2', true)
.attr('attr3', attr3val)
.on('click', function() {
d3.select(element[0])
.attr('attr3', function() {
attr3val++;
console.log("new attr3 value is", attr3val);
return attr3val;
});
});
element.removeAttr("attr1");
$compile(element)(scope);
}
};
})
.directive('attr2', function() {
return {
restrict: 'A',
scope: {
attr3: "=attr3"
},
link: function(scope, element, attrs) {
scope.$watch('attr3', function() {
console.log('attr3 modification trigger');
});
}
};
});
They are shown in action here - console logs have to be activated to understand clearly what happens.
Following this thread, I use $compile
so that the attr2
directive is effectively bound after the DOM is modified by d3 calls. I then would like to watch the changes of another attribute (attr3
here). Using a private scope in attr2
, I thought this to be possible, but I must be doing something wrong, as clicks in the blue square do indeed update the attribute value, but without the watch being triggered.
Maybe DOM attributes are not "watchable"? Are the only viable solutions those prescribed here?
Thanks by advance for your keen help!
EDIT
The solution using $broadcast
shown hereunder is working strictly speaking, but is ineffective if the attribute is common to many elements, and I want to watch one specifically. I'm thus going for a $watch
on a function evaluation that uses jQuery, as shown here.