AngularJS ng-repeat update does not apply when object keys stay the same? -
i'm trying make minimal fancy angularjs tutorial example, , running issue after updating entire tree model (inside scope of ng-change update), template driven top-level ng-repeat not re-rendered @ all.
however, if add code $scope.data = {}
@ strategic place, starts working; display flashes instead of being nice , smooth. , it's not great example of how angularjs automatic data binding works.
what missing; , right fix?
exact code - select country dropdown - jsfiddle not work: http://jsfiddle.net/f9zxt36g/ jsfiddle works flickers: http://jsfiddle.net/y090my10/
var app = angular.module('factbook', []); app.controller('loadfact', function($scope, $http) { $scope.country = 'europe/uk'; $scope.safe = function safe(name) { // makes safe css class name return name.replace(/[_\w]+/g, '_').tolowercase(); }; $scope.trunc = function trunc(text) { // truncates text 500 chars return (text.length < 500) ? text : text.substr(0, 500) + "..."; }; $scope.update = function() { // handles country selection // $scope.data = {}; // uncomment force rednering; angular bug? $http.get('https://rawgit.com/opendatajson/factbook.json/master/' + $scope.country + '.json').then(function(response) { $scope.data = response.data; }); }; $scope.countries = [ {id: 'europe/uk', name: 'uk'}, {id: 'africa/eg', name: 'egypt'}, {id: 'east-n-southeast-asia/ch', name: 'china'} ]; $scope.update(); });
the template driven ng-repeat:
<div ng-app="factbook" ng-controller="loadfact"> <select ng-model="country" ng-change="update()" ng-options="item.id item.name item in countries"> </select> <div ng-repeat="(heading, section) in data" ng-init="depth = 1" ng-include="'recurse.template'"></div> <!-- template nested sections heading , body parts --> <script type="text/ng-template" id="recurse.template"> <div ng-if="section.text" class="level{{depth}} section fact ng-class:safe(heading);"> <div class="level{{depth}} heading factname">{{heading}}</div> <div class="level{{depth}} body factvalue">{{trunc(section.text)}}</div> </div> <div ng-if="!section.text" class="level{{depth}} section ng-class:safe(heading);"> <div class="level{{depth}} heading">{{heading}}</div> <div ng-repeat="(heading, body) in section" ng-init="depth = depth+1; section = body;" ng-include="'recurse.template'" class="level{{depth-1}} body"></div> </div> </script> </div>
what missing?
you changed reference of section
property executing section = body;
inside of ng-if
directives $scope
. happened in details (https://docs.angularjs.org/api/ng/directive/ngif):
ng-repeat
ondata
created$scope
ng-repeat
propertiesheading
,section
;- template
ng-include
$compile
'd$scope
1st step; - according documentation
ng-if
created own$scope
using inheritance , duplicatedheading
,section
; ng-repeat
inside of template executedsection = body
, changed reference pointsection
property insidengif.$scope
;- as
section
inherited property, directed displayingsection
property$scope
, different initial$scope
of parent ofngif
.
this traced - add:
... <script type="text/ng-template" id="recurse.template"> {{section.background.text}} ...
and notice section.background.text
appoints proper value , changed accordingly while section.text
under ngif.$scope
not changed ever.
whatever update $scope.data
reference, ng-if
not cares it's own section
still referencing previous object not cleared garbage collector.
reccomdendation: not use recursion in templates. serialize response , create flat object displayed without need of recursion. template desired display static titles , dynamic texts. that's why have lagging rendering - did not used one-way-binding such static things section titles. some performance tips.
p.s. recursion not in template @ business logic place when manage data. ecmascript sensitive references , best practice keep templates simple - no assignments, no mutating, no business logic in templates. angular goes wild $watcher
's when updating every of section
many times without end.
Comments
Post a Comment