2014-09-09 1 views
6

У меня есть код, который создает сетку, как это:Есть ли способ ускорить работу моей сетки, когда у меня много строк?

<div ng-repeat="row in home.grid.data track by row.examId"> 
    <div>{{ row.examId }}</div> 
    <div>xxxx</div> 
</div> 

У меня есть несколько столбцов после них.

Есть ли способ ускорить работу моей страницы? Кажется, что когда у меня много данных в сетке, тогда страницы реагируют медленно. Будет ли это иметь значение, если я использовал ng-модель в поле типа ввода для row.examId. Обратите внимание: можно изменить некоторые из следующих полей, но большинство из них только отображаются.

+0

Саманты, нужен более тщательный пример данных, которые являются обязательными и потенциально formmating фильтров и т.д. Кроме того, необходимо понять, как много данных ... Сколько строк и как часто данные изменяются/перезагружаются ... –

+0

Сколько строк вы имеете в виду? –

ответ

4

Я считаю, bindonce делает именно то, что вам нужно.

Уменьшая количество наблюдателей, он позволяет странице стать более отзывчивой. Проверьте их demos.

+0

Это довольно круто. Я могу придумать несколько мест, которые я мог бы использовать. – adam0101

+0

Я не думаю, что здесь используется 'bindonce'. ** Есть ли способ ускорить реакцию моей страницы? ** OP обвинили, что редактирование доступно для некоторых полей. Таким образом, удаление всех часов улучшило производительность, удалив функциональность –

+0

Официальное 'bindonce' должно использовать' :: 'в начале любого свойства/выражения scope с версии' 1.3.0' – bhantol

1

Самое большое, что я нашел, чтобы помочь с выполнением больших таблиц, - ограничить привязку событий к родительскому объекту и использовать пузырьки для захвата событий детей.

В случае родителя вы можете получить, какая цель была удалена. Я использую следующий код.

obj.onclick = function (e) { 
    e = window.event || e; 
    var t = e.target || e.srcElement; 
} 

В этом случае е является вашим обычным объектом события и т является объектом, который был первоначальной целью до события ого. Вы должны использовать t как 'this' ссылается на объект, которому событие связано не с объектом, который вызвал событие.

Где я использовал код, который был действительно большой таблицей, он уменьшил время рендеринга таблицы почти на 80%, переместив события на родительский узел, который был статичным. Это также помогает, если вам необходимо обновить содержимое, поскольку вам не нужно повторно связывать какие-либо события.

Надеюсь, это поможет.

4

Это то, что я сделал. Есть два пути. Независимо от обоих решений, используйте bindOnce. Следите за количеством наблюдателей на странице. Посмотрите на конец этого решения - как отслеживать наблюдателей на странице.

Я добавляли раствор 3, и это работает удивительным, укладка немного трудно

Решение 1:

Использование управления нумерацией страниц с затруднительное один раз.

Решение 2 Это то, что сработало для меня, и оно очень элегантно. Вы повторяетесь с bindonce, а затем реализуете бесконечную прокрутку. Я следил за this blog post, и он работает как шарм. Идея заключается в том, что вы ограничиваете количество строк и изменяете лимит при прокрутке.

ng-repeat="item in items | orderBy:prop | filter:query | limitTo:limit" 

По существу, ваш html будет выглядеть так. Я изменил код OP для использования bindonce.

<div id="estates-listing" extend-height> 
    <div class="content" infinite-scroll="addMoreItems()" infinite-scroll-distance="2"> 
    <div class="content-wrapper"> 
     <div class="house" bindonce="estate" ng-animate="'animate'" ng-class="{inactive: (selectedEstate != null || selectedEstate != undefined) && estate.id!=selectedEstate.id , active:(selectedEstate != null || selectedEstate != undefined) && estate.id==selectedEstate.id}" ng-repeat="estate in estates | orderBy: orderProp : orderReverse | limitTo: config.itemsDisplayedInList track by estate.id" ng-mouseover="highlightMarker(estate)" ng-mouseleave="leaveMarker(estate)" ng-click="showDetailview(estate.id)" > 
     <div id="l-el{{estate.id}}"> 
     </div> 
     </div> 
    </div> 
    </div> 
</div> 

Вот бесчисленная директива свитка с поста. Добавьте это в свое приложение, пожалуйста, не используйте стандартную бесконечную прокрутку с помощью установки bower.

app.directive('infiniteScroll', [ 
    '$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) { 
    return { 
     link: function(scope, elem, attrs) { 
     var checkWhenEnabled, handler, scrollDistance, scrollEnabled; 
     $window = angular.element($window); 
     elem.css('overflow-y', 'scroll'); 
     elem.css('overflow-x', 'hidden'); 
     elem.css('height', 'inherit'); 
     scrollDistance = 0; 
     if (attrs.infiniteScrollDistance != null) { 
      scope.$watch(attrs.infiniteScrollDistance, function(value) { 
      return scrollDistance = parseInt(value, 10); 
      }); 
     } 
     scrollEnabled = true; 
     checkWhenEnabled = false; 
     if (attrs.infiniteScrollDisabled != null) { 
      scope.$watch(attrs.infiniteScrollDisabled, function(value) { 
      scrollEnabled = !value; 
      if (scrollEnabled && checkWhenEnabled) { 
       checkWhenEnabled = false; 
       return handler(); 
      } 
      }); 
     } 
     $rootScope.$on('refreshStart', function(event, parameters){ 
      elem.animate({ scrollTop: "0" }); 
     }); 
     handler = function() { 
      var container, elementBottom, remaining, shouldScroll, containerBottom; 
      container = $(elem.children()[0]); 
      elementBottom = elem.offset().top + elem.height(); 
      containerBottom = container.offset().top + container.height(); 
      remaining = containerBottom - elementBottom ; 
      shouldScroll = remaining <= elem.height() * scrollDistance; 
      if (shouldScroll && scrollEnabled) { 
      if ($rootScope.$$phase) { 
       return scope.$eval(attrs.infiniteScroll); 
      } else { 
       return scope.$apply(attrs.infiniteScroll); 
      } 
      } else if (shouldScroll) { 
      return checkWhenEnabled = true; 
      } 
     }; 
     elem.on('scroll', handler); 
     scope.$on('$destroy', function() { 
      return $window.off('scroll', handler); 
     }); 
     return $timeout((function() { 
      if (attrs.infiniteScrollImmediateCheck) { 
      if (scope.$eval(attrs.infiniteScrollImmediateCheck)) { 
       return handler(); 
      } 
      } else { 
      return handler(); 
      } 
     }), 0); 
     } 
    }; 
    } 
]); 

Решение 3: Будьте предприимчивы и использовать UI-Grid, UI Сетка является новым нг сетки. Это не производство готово, но мы играем в производстве в таблице, где у нас более 1000 записей - из коробки это потрясающе. Учебники обширны, но не поддерживают SO. Он имеет встроенную виртуализацию и, поскольку он является расширением ng-grid, имеет много обратной совместимости. Вот пример с 10,000 rows

Количество наблюдателей на странице: Вот функция, чтобы отслеживать количество наблюдателей на этой странице. Эмпирическое правило никогда не превышает 2500 наблюдателей, но мы ограничимся < 1000.

$scope.TotalWatchers = function() { 
       var root = $(document.getElementsByTagName('body')); 
       var watchers = 0; 

       var f = function (element) { 
        if (element.data().hasOwnProperty('$scope')) { 
         watchers += (element.data().$scope.$$watchers || []).length; 
        } 

        angular.forEach(element.children(), function (childElement) { 
         f(angular.element(childElement)); 
        }); 
       }; 

       f(root); 

       return watchers; 
      }; 
Смежные вопросы