javascript - AngularJS - problems with $onChanges -
i have object defined in parent component , passed in one-way binding first-child , second-child components. first-child component make changes in object. cannot understand why in second-child component $onchanges doesn't fire if object have changed something.
i have project build in snippet (link jsfiddle completeness)
angular.module('test', []) .component('parent', { template: "<first-child bind='vm.obj'></first-child>\ <second-child bind='vm.obj'></second-child>\ ", controller: function(){ this.obj = {value: 0}; this.$oninit = function(){} }, controlleras: 'vm', bindings: {} }) .component('firstchild', { template: "<button ng-click='vm.plus()'>+</button>\ <button ng-click='vm.minus()'>-</button>\ ", controller: function(){ this.plus = function(){ this.bind.value++; } this.minus = function(){ this.bind.value--; } this.$oninit = function(){} this.$onchanges = function(obj){ console.log('first-child changed one-way bindings', obj) } }, controlleras: 'vm', bindings: { bind: '<' } }) .component('secondchild', { template: "<p>{{vm.bind.value}}</p>", controller: function(){ this.$oninit = function(){} this.$onchanges = function(obj){ console.log('second-child changed one-way bindings', obj) } }, controlleras: 'vm', bindings: { bind: '<' } }) <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body ng-app="test"> <parent></parent> </body> so question is, there way fire $onchanges in situation?
edit
$onchanges doesn't fire if define array in parent, pass first-child , second-child in one-way binding , in first-child push something. in case object has changed, still don't undertand why.
you have little misunderstanding in one-way usage. one-way triggers $onchanges if object changes, not if property of object changes.
you must bind directly value in second-child, not full object.
here solution problem :
angular.module('test', []) .component('parent', { template: " <first-child bind='vm.obj'></first-child>\ <second-child value='vm.obj.value'></second-child>\ ", controller: function(){ this.obj = {value: 0}; this.$oninit = function(){} }, controlleras: 'vm', bindings: {} }) .component('firstchild', { template: " <button ng-click='vm.plus()'>+</button>\ <button ng-click='vm.minus()'>-</button>\ ", controller: function(){ this.plus = function(){ this.bind.value++; } this.minus = function(){ this.bind.value--; } this.$oninit = function(){} this.$onchanges = function(obj){ console.log('first-child changed one-way bindings', obj) } }, controlleras: 'vm', bindings: { bind: '<' } }) .component('secondchild', { template: "<p>{{vm.value}}</p>", controller: function(){ this.$oninit = function(){} this.$onchanges = function(obj){ console.log('second-child changed one-way bindings', obj) } }, controlleras: 'vm', bindings: { value: '<' } }) as advise think should work two-way in first child directly on value , one-way in second-child directly value too.
your fiddle correction
Comments
Post a Comment