I'm using UI-Select 0.8.4 and have a large data set. Then I'm using UI-Select to display property values in a dropdown beside the data set. I'm using that for filters. So when choosing from the dropdown, will filter the results.
Every time when I hover over some item in the dropdown, it always fires the ng-repeat filter.
This is lagging my application because I'm working with a large set in the ng-repeat.
Why is this?
GIF: http://i.imgur.com/cStlXzy.gif
Plunker (open console and see for yourself): http://plnkr.co/edit/OxiutZ8t4IX1bOxiOTgo?p=preview
HTML:
<h3>Age list</h3>
<p>Selected: {{age.selected}}</p>
<ui-select ng-model="age.selected" ng-disabled="disabled" style="width: 300px;">
<ui-select-match placeholder="Select a person">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="age in ageArray | filter: $select.search">
<div ng-bind="age | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
JavaScript:
$scope.theFilter = function(item) {
console.log(item);
return item;
};
$scope.ageArray = [];
$scope.$watch('people', function(item) {
for(var i = 0; i < item.length; i++) {
$scope.ageArray.push(item[i].age);
}
});
$scope.people = [
{ name: 'Adam', email: '[email protected]', age: 10 },
{ name: 'Amalie', email: '[email protected]', age: 12 },
{ name: 'Wladimir', email: '[email protected]', age: 30 },
{ name: 'Samantha', email: '[email protected]', age: 31 },
{ name: 'Estefanía', email: 'estefaní[email protected]', age: 16 },
{ name: 'Natasha', email: '[email protected]', age: 54 },
{ name: 'Nicole', email: '[email protected]', age: 43 },
{ name: 'Adrian', email: '[email protected]', age: 21 }
];
Edit: I even tried to filter the property values out of the "data set array" and using that in the dropdown, but it doesn't work.
Edit 2: If you think that the watch was triggering this, I removed the watch and this is still a problem: http://plnkr.co/edit/oD3Tt3vfjtOjADMnemW1?p=preview
Edit 3: Still haven't found a solution for this so I'm stuck with chosen. I created an issue but haven't gotten any response. Please upvote the issue if you want this fixed.
The issue is that the filter is executing on every $digest
(every ng-mouseenter, ng-click, etc). For a huge data set, this can obviously kill performance. (See this article http://www.bennadel.com/blog/2489-how-often-do-filters-execute-in-angularjs.htm)
Instead, try a $watch
on the age.selected
value, then applying a filter only when that value actually changes.
http://plnkr.co/edit/TIeKPAyrAQsGHwakqwEp?p=preview
HTML
<!-- filtered list "ageMatches" -->
<ul ng-show="age.selected">
<li ng-repeat="person in ageMatches">{{person.name}} - {{person.age}}</li>
</ul>
<!-- default list of all "people" -->
<ul ng-hide="age.selected">
<li ng-repeat="person in people">{{person.name}} - {{person.age}}</li>
</ul>
JS
// add age to scope
$scope.age = {};
// add age match placeholder
$scope.ageMatches = [];
// watch age.selected for changes, apply filter
$scope.$watch('age.selected', function(newVal, oldVal){
if(newVal){
$scope.ageMatches = $filter('filter')($scope.people, {age: newVal});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With