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.id
s, 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