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
Post a Comment