user2912840
user2912840

Reputation: 11

AngularJS: How do I get a directive to update when the data changes?

I am trying to get a directive to update when the data changes in my controller... currently I have gotten the ng-repeat to update some of the values but the directive inside the repeat does not appear to get called again.

I have a directive like so:

app.directive("donut", function () {
return {
    restrict: 'E',
    scope: {
        donut: '='
    },
    replace: true,
    link: link
};

function link($scope, $elem, $attr) {
    var chart = {
        //chart functionality
    }
    $scope.$watch($scope.donut,function(){chart.createChart($elem, $scope.donut)});
}
}

I have this in my html:

<donut class="donut-holder-inventory" donut="data.donutData"></donut>

And then I have this in the controller:

$scope.regions = [
    {
        region: 'Team Number One',
        data: [
            {
                title: 'Number One',
                subtitle: 'Quantity Available',
                daysSupply: 0,
                targetNumber: 108,
                actualNumber: 46,
                targetPercentage: 1,
                actualPercentage: 0,
                color: 'red',
                donutData: {
                    name: 'Number One',
                    fullscale: false,
                    fullsection: 108,
                    values: [46],
                    labeltext: ['% to goal'],
                    labelunits: "percent",
                    color: ["#f44336"],
                    labels: false,
                    height: 150
               }
           }
       }
  ]

Then I have this timeout in the controller just to test the data binding:

function timerFunc(dat) {
    $scope.$apply(function () {
        console.log("changing")
        var dat = $scope.regions;
        for (var x = 0; x < dat.length; x++) {
            var cdat = dat[x].data;
            for (var c = 0; c < cdat.length; c++) {
                console.log(cdat[c].targetNumber)
                var nval = Math.round($scope.regions[x].data[c].actualNumber + (Math.random() * 1000))
                $scope.regions[x].data[c].targetNumber = nval;
                $scope.regions[x].data[c].donutData.fullsection = nval;
            }
        }
    });
};
var timer = setInterval(function () {
    timerFunc()
}, 1000);

The donut directive is bound to the .donutData property, the rest of the view updates but the donut directive does not, what do I need to do to make the directive run its link function again?

Upvotes: 0

Views: 163

Answers (1)

Simon Sch&#252;pbach
Simon Sch&#252;pbach

Reputation: 2683

Call $watch with true as the third argument:

 $scope.$watch("donut", function(){chart.createChart($elem, $scope.donut)}, true);

By default when comparing two complex objects in JavaScript, they will be checked for "reference" equality, which asks if the two objects refer to the same thing, rather than "value" equality, which checks if the values of all the properties of those objects are equal.

Upvotes: 1

Related Questions