-
-
Save dzNavitski/8f62b7e09f5976700656af13239bed0e to your computer and use it in GitHub Desktop.
SimpleVirtualRepeater - This is an simple solution to handle thousands of results on an ng-repeat without sacrificing performance.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() { | |
| 'use strict'; | |
| angular.module('simple-virtual-repeater', []) | |
| .directive('virtualRepeater', virtualRepeater); | |
| virtualRepeater.$inject = ['$compile', '$timeout']; | |
| function virtualRepeater($compile, $timeout) { | |
| var directive = { | |
| restrict: 'EA', | |
| replace: 'true', | |
| transclude: true, | |
| template: '<div class="virtual-repeat"><div class="virtual-repeat-before"></div><div ng-transclude=""></div><div class="virtual-repeat-after"></div></div>', | |
| link: function postLink(scope, iElement, iAttrs, controller) { | |
| var internalRepeat = iElement.find("[ng-transclude]"), | |
| beforeRepeat = iElement.find(".virtual-repeat-before"), | |
| afterRepeat = iElement.find(".virtual-repeat-after"), | |
| parent = iElement.parent(); | |
| internalRepeat.hide(); | |
| var expressionMatches = /^\s*(\S+)\s+in\s+([\S\s]+?)(track\s+by\s+\S+)?$/.exec(iAttrs.virtualRepeat), | |
| lhs = expressionMatches[1], | |
| rhs = expressionMatches[2], | |
| rhsSuffix = expressionMatches[3] || ''; | |
| var itemsAllowed = +(iAttrs.itemsAllowed || 5), totalItems = [], itemHeight = 0; | |
| var repeater = angular.element('<div class="virtual-repeat-item" ng-repeat="' + lhs + ' in virtualRepeatCollection ' + rhsSuffix + '"></div>'); | |
| repeater.html(internalRepeat.html()); | |
| scope.virtualRepeatCollection = []; | |
| scope.$watchCollection(rhs, function (data) { | |
| if (data) { | |
| totalItems = data; | |
| scope.virtualRepeatCollection = totalItems.slice(0, itemsAllowed); | |
| $timeout(function () { | |
| itemHeight = iElement.find(".virtual-repeat-item:first").height(); | |
| parent.scrollTop(0); | |
| beforeRepeat.css("height", 0); | |
| afterRepeat.css("height", itemHeight * (totalItems.length - itemsAllowed)); | |
| }); | |
| } | |
| }); | |
| internalRepeat.after($compile(repeater)(scope)); | |
| parent.on('scroll', function () { | |
| var movedDistance = parent.scrollTop(), | |
| movedItems = Math.floor(movedDistance / itemHeight); | |
| movedItems = (movedItems > 0)? movedItems - 1 : 0; | |
| scope.virtualRepeatCollection = totalItems.slice(movedItems, movedItems + itemsAllowed); | |
| beforeRepeat.css("height", itemHeight * (movedItems)); | |
| afterRepeat.css("height", itemHeight * (totalItems.length - movedItems - itemsAllowed)); | |
| scope.$apply(); | |
| }); | |
| } | |
| }; | |
| return directive; | |
| }; | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment