Zhe Hu February 2016

javascript closure or not (while using angularjs directive and d3js)

Inspired by this example angular directive with 2-way binding, I made a simple directive, once clicked will change the value on the parent scope codepen live.

.directive("haha", function() {
return {
  scope: {
    v: '='
  },
  template: `<div ng-click="myfun()">click me now</div>`,
  link: function(scope, element) {
    scope.myfun = function() {
      scope.v  = "clicked";
    }       
  }
}
});

Now I add a svg circle drawn with d3 inside "link", and try to add a similar event handler with d3.on

d3.select(element[0]).append("svg").attr({width:300,height:300})
      .append("circle").attr({cx:100,cy:100,r:20})
      .on("click",function(){scope.v="clicked inside d3"; alert(scope.v)});

When I click the circle, {{value}} on html page doesn't change. codepen live

Isn't it correct, as javascript closure rule, inside on("click", function() ..., scope.v should still be the same as scope from link: function(scope...

Answers


Amir Popovich February 2016

You need to add scope.$apply since you are updating your scope "outside" the "angular world" and you want angular to run a digest cycle.

d3.select(element[0]).append("svg").attr({width:300,height:300})
      .append("circle").attr({cx:100,cy:100,r:20})
      .on("click",function(){scope.$apply(function(){scope.v="clicked inside d3";})});

Codepen.

Post Status

Asked in February 2016
Viewed 2,622 times
Voted 11
Answered 1 times

Search




Leave an answer