i have the following directive:
app.directive('rickshawChart', function()
{
return{
$scope: {
data: '=',
renderer: '='
},
template: '<div></div>',
restrict: 'E',
link: function postLink(scope, element, attrs)
{
scope.$watchCollection('[data,renderer]', function(newVal, oldVal)
{
if(!newVal[0])
{
return;
}
var graphEl = element.find("div:first");
graphEl.html('');
var graph = new Rickshaw.Graph({
element: graphEl[0],
width: attrs.width,
height: attrs.height,
series: [{data: scope.data, color: attrs.color, name: attrs.series}],
renderer: scope.renderer
});
graph.render();
});
}
}
});
With the following html:
<rickshaw-chart
data="sightingByDate"
color="green"
renderer="renderer"
width="100%"
height="100%">
</rickshaw-chart>
Here i fill the data in with the following controller:
app.controller('CompetenceController', ['$http', '$scope','$sessionStorage','$log','Session','api', function ($http, $scope, $sessionStorage,$log, Session, api) {
$scope.result =[ { x: 0, y: 40 }, { x: 1, y: 49 }, { x: 2, y: 38 }, { x: 3, y: 30 }, { x: 4, y: 32 } ];
$scope.renderer = 'scatterplot';
$scope.sightingsByDate = _($scope.result)
.chain()
.countBy(function(sighting){
return sighting.y;
})
.pairs()
.map(function(pair){
return pair;
})
.value();
}]);
however from the debugger i am able to see that the $watchCollection
is never executed.
What am i doing wrong?
You should use the $watch
expression with true
as a third parameter:
scope.$watch('[data,renderer]', function (newVal, oldVal) {
//code
}, true);
$watchCollection
doesn't work for you because you have both an array and a property. In this case is like you're checking contemporarily $scope.$watch('data'
and $scope.$watch('renderer'
. And if a property in the array changes, the event will not trigger.
There are four types of $watch
:
$watch
, it simply check if the property or the whole object changed$watchCollection
which watches if any property within an array changed (in your case this doesn't work, because you have both an array and a property)$watchGroup
(since 1.3) which is the most recent version of $watchCollection
, which allows you to check an array of expressions (but the same could be achieved with $watchCollection
as you were trying to do$watch('object', function(){...}, true)
. This check if every single property changed within an objectThis is a simplified version of your code, if you press the change value button, you can see how an element in the array is changed and how the event is triggered in the console: http://jsfiddle.net/27gc71bL/
EDIT: I forgot to add something in my answer. I think there's a typo in your code, you are creating a directive using:
$scope: {
data: '=',
renderer: '='
},
This is not creating a new scope within the directive. So when you are using scope.data
in the link function, you are referring to the $scope.data
of the parent (the controller).
What I think you wanted, is to create a new scope in this way:
scope: {
data: '=',
renderer: '='
},
and, in your controller, bind the array you want to check to sightingByDate
.
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