0

Hey I am trying to pass some data in a form of json object from the controller to a component , I using the annotation of '<' and listen to changes on field in the $onChanges method.

But apparently angular sense only one change, although I update the field (data field of current component) every 2 seconds using interval. I have try to use the annotation of '=' but then I can't listen to changes on the object using $onChanges event. So what can I do to solve this problem? Maybe I'm doing something which isn't right.

var app = angular.module("app",[]);
app.component('heroDetail', {
  template: '<span>Name</span>',
  controller: HeroDetailController,
  bindings: {
    data: '<'
  }
});

function HeroDetailController(){
  this.$onChanges = function(changes){
    console.log("changes",changes);
  }
}

app.controller('mainController',function($scope,$interval){
    trendData = {
        Load: [],
        AVGTemperature: [],
        IR: [],
        Acoustic: []
    }
  $interval(function () {
        for (var key in trendData) {
            trendData[key] = [];
            trendData[key].push((new Date()).getTime());
            trendData[key].push(Math.round(Math.random() * 100));
        }
        console.log("$scope.trendData",$scope.trendData)
        $scope.trendData = trendData;
    }, 2000);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div ng-app="app" ng-controller="mainController">
  <hero-detail data="trendData"></hero-detail>
</div>

1
  • See if this works for you - change your binding to @ and assign to the data attribute as data="{{trendData | json}}" - to bind on a string representation of your json. All changes will be reflected since your are no longer watching a reference but a string. Commented Dec 20, 2016 at 15:22

2 Answers 2

1

In component architecture common way of passing data between components is to not mutate data but always create new copied structures with new reference. This is only way to monitor data flow in our application, because the easiest and most effective way of checking that something was change is to check only reference without deep checking of every property in object, and this is what exactly component lifecycle is doing.

I must mention that mutating object will refresh the scope in children but will not be monitored as change in component lifecycle. So digest loop will see changes in object, but component lifecycle will not catch those changes.

To fix Your example code to be sure that all changes are monitored by $onChanges we need to create new copy of array on every change. Take a look:

$interval(function () {

    var trendData=$scope.trendData.slice(); //create copy of array
    for (var key in trendData) {
        trendData[key] = [];
        trendData[key].push((new Date()).getTime());
        trendData[key].push(Math.round(Math.random() * 100));
    }
    $scope.trendData = trendData; //we are setting new reference to copied array
}, 2000);
Sign up to request clarification or add additional context in comments.

2 Comments

While this works, I would suggest using $watch in the component itself with objectEquality set to true. This way you are not rebuilding a new object for every minor change.
@sledsworth i disagree with Your opinion, using components lifecycle is something different than using old fashion watch, I can say more if We are using components lifecycle watch should not be used at all. Creating new object copy is better than deep object watching. Components data flow is based on reference change.
1

Objects that are passed through one-way binding are passed by reference. The $watch that is working behind the scenes does NOT check for object equality, just that the references are the same. This means the $watch is never dirtied and a change will never be picked up. To realize a change to an object you will have to set a watch with the objectEquality flag set in the component. More on this can be found:

https://docs.angularjs.org/api/ng/type/$rootScope.Scope http://blog.kwintenp.com/the-onchanges-lifecycle-hook/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.