angularjs - ng-if being called more times than it should -
i'm trying filter channels depending on selected category.
i have ng-repeat of channel in channels
has ng-if="hascategory(channel.category)
here's document:
db.channels.find().pretty() { "_id" : "2kj9gk8je9yhezowb", "name" : "example name", "logo" : "path/to/image.svg", "number" : 2, "category" : [ "broadcast", "premium" ], "tags" : "example tag tags" }
this function handle ng-if:
$scope.hascategory = function (categorynamearray) { console.log('thisisbeingcalled'); var e = _.indexof(categorynamearray, $scope.activecategory); if (e === -1) { return false; } else { return true; } };
and how set active category:
$scope.setcategory = function (name) { $scope.activecategory = name; };
which send clicking button in view:
<section layout="row" layout-align="center center" layout-wrap ng-init="activeindex; activecategory"> <md-button flex="auto" flex-sm="45" flex-xs="100" ng-repeat="kit in kits | orderby: 'order'" ng-class="{active: (activeindex.index == $index)}" class="md-raised"> <a href="" ng-click="activeindex.index = $index; setcategory(kit.name);" class="bold">{{kit.name}}</a> </md-button> </section>
here's kits document schema:
db.kits.find().pretty() { "_id" : "k7jfx6dhu5gynyer3", "name" : "broadcast", "order" : 1 } { "_id" : "krkrm4gysw5sfqnnr", "name" : "premium", "order" : 2 } { "_id" : "dieukq3nrsa44csns", "name" : "ultimate", "order" : 3 }
now have 1 channel test out, each time click button change category, $scope.hascategory
function gets called multiple times @ startup of page (first time loading)
i have search bar search channels in current category, i'm not sure if affects well.
<input type="text" ng-model="queryname" ng-model-options="{debounce: 500}">
now gets laggy when have more 100 channels, ng-if gets called more 10k times, makes page freeze quite while.
what can fix issue?
edit
forgot add ng-if
was:
<md-card flex="15" flex-xs="40" class="slide-up" layout="column" ng-repeat="channel in channels | orderby: 'number' | filter: queryname" ng-if="hascategory(channel.category)" ng-init="channel.edit = false"> <md-card-header ng-show="channel.edit == false"> <img ng-src="{{channel.logo}}" alt=""> </md-card-header> <md-card-header-text ng-show="channel.edit == false"> <span class="md-subhead dark-blue" layout="row" layout-align="center" layout-margin>{{channel.number}}</span> </md-card-header-text> </md-card>
your ng-if
called on every digest loop. problem contains expression involving function call. angular has no way know when result of expression might change, calls every time.
a better option set flag in each of channels , use ng-if test relevant flag. have update flags whenever $scope.activecategory
changes can either code set category or using $scope.$watch()
trigger automatically.
e.g.
$scope.setcategory = function (name) { $scope.activecategory = name; (var index=0; index < $scope.channels.length; index++) { $scope.channels[index].hascategory = hascategory($scope.channels[index].category, name); } }; function hascategory(categorynamearray, name) { console.log('thisisbeingcalled'); var e = _.indexof(categorynamearray, name); if (e === -1) { return false; } else { return true; } }
then in template:
<md-card flex="15" flex-xs="40" class="slide-up" layout="column" ng-repeat="channel in channels | orderby: 'number' | filter: queryname" ng-if="channel.hascategory" ng-init="channel.edit = false"> <md-card-header ng-show="channel.edit == false"> <img ng-src="{{channel.logo}}" alt=""> </md-card-header> <md-card-header-text ng-show="channel.edit == false"> <span class="md-subhead dark-blue" layout="row" layout-align="center" layout-margin>{{channel.number}}</span> </md-card-header-text> </md-card>
should more efficient.
Comments
Post a Comment