AngularJS: ng-repeat track by obj.id doesn't reinitialise transcluded content when obj.id changes -


function componentcontroller() {    var vm = this;    this.$oninit = function() {      vm.link = 'http://example.com/obj/' + vm.obj.id;    }  }  function maincontroller($scope, $timeout) {    $scope.arrobjs = [{id: 1, name: "object1"},{id: 2, name: "object2"}];      console.log('object1\'s id ', $scope.arrobjs[0].id);    $timeout(function() { // simulates call server updates id      $scope.arrobjs[0].id = '3';      console.log('object1\'s new id ', $scope.arrobjs[0].id, '. expected link above updated new id');    }, 1000);  }  var somecomponent = {    bindings: {      obj: '='    },    template: '<div>url: <span>{{$ctrl.link}}</span></div>',    controller: componentcontroller  };    angular.module('myapp', []);  angular      .module('myapp')      .controller('maincontroller', maincontroller)      .controller('componentcontroller', componentcontroller)      .component('somecomponent', somecomponent);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>  <div ng-app="myapp">    <div ng-controller="maincontroller">      <div ng-repeat="obj in arrobjs track obj.id">        <some-component obj="obj"></some-component>      </div>    </div>  </div>

after ng-repeat , somecomponent rendered 1 of objects' obj.id changes (using $timeout in above example). vm.link object still carries old id!

now, know $oninit() run once inside somecomponent, why doesn't track by re-initialise component because obj.id changed?

if angular tracked array obj.ids, should treat obj id changes different object , re-initialise it, no?

obviously $watch on vm.obj.id within somecomponent fix it, there way without adding yet $watch?

note: using

<div ng-repeat="objid in vm.arrobjids track objid" ng-init="obj = vm.fnlookupobjbyid(objid)">   <somecomponent obj="obj"></somecomponent> </div> 

and works perfectly! how expected track obj.id work. i'm trying move away ng-init pattern.

you're missing somewhere in code you're not showing us.

the following snippet works.

init() not standard function though. mean $oninit()

function componentcontroller() {    var vm = this;    console.log("not in init: " + this.obj.id);    this.$oninit = function() {      console.log("in init: " + vm.obj.id);    }  }  function maincontroller($scope) {    $scope.arrobjs = [{id: 1, name: "object1"},{id: 2, name: "object2"}];  }  var somecomponent = {    bindings: {      obj: '='    },    template: '<div>id: <span>{{$ctrl.obj.id}}</span></div>',    controller: componentcontroller  };    angular.module('myapp', []);  angular      .module('myapp')      .controller('maincontroller', maincontroller)      .controller('componentcontroller', componentcontroller)      .component('somecomponent', somecomponent);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>  <div ng-app="myapp">    <div ng-controller="maincontroller">      <div ng-repeat="obj in arrobjs track obj.id">        <some-component obj="obj"></some-component>      </div>    </div>  </div>

edit:

if add asynchronous function in middle, compiling of code faster return of async function.

using $watch standard way of updating view when data changes. there's not other way.

note: components can use $onchanges() in particular case won't trigger since have change reference of object update. $onchanges() calls $watch in case.


Comments

Popular posts from this blog

serialization - Convert Any type in scala to Array[Byte] and back -

matplotlib support failed in PyCharm on OSX -

python - Matplotlib: TypeError: 'AxesSubplot' object is not callable -