English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Методы замены ng-repeat пользовательскими директивами в AngularJS

Введение

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

Выражения в ng-repeat и $watch

Все выражения в Angular создают функцию Scope $watch. Используется для отслеживания изменений модели, когда часть модели изменяется, она уведомляет вас. В инструкции ng-repeat, если строка данных имеет 15 связанных выражений, и если данных более 1000 строк, то $watch создаст 15000, это производительность просто难以 представить.

Таким образом, когда мы хотим реализовать функциональность ng-repeat и обладать производительностью, мы должны найти другой способ.

Замена метода ng-repeat

Если содержимое статическое, нам не нужно два способа привязки, достаточно выполнить одно присваивающее выражение {{::value}}, если angularJS версии 1.3 и ниже, поддержка一次性 привязки выражений.

Шаги реализации

1. Сначала создайте unordered list для хранения динамически привязанного содержимого.

Создание тега UL в качестве контейнера для отображения списка

Мы выбираем динамическую загрузку данных из списка, сначала добавляем тег div и называем его "repeater-alternative", чтобы отобразить его в потоке.

<div>
 <ul>
  <div repeater-alternative></div>
 </ul>
</div>

2. Определение данных списка:

// Пример данных
var studentsList = 
[
 {
  FirstName: "Raj,"
  LastName : "B",
  Country : "India",
  BirthDate: "01/01/1990"
 },
 {
  FirstName: "Kumar,"
  LastName : "S",
  Country : "India",
  BirthDate: "01/01/1990"
 },
 ..................
 ..................
 ..................
 ..................
];
$scope.collectionObject = studentsList; // Assign to $scope function

3. Реальное содержимое списка

Основная цель подходит для повторяющихся объектов набора и отображения их в списке, поэтому необходимо определить логику доступа цикла и форматировать строки по запросу.

var tableRow = "";
angular.forEach($scope.collectionObject, function (item) {
  tableRow = tableRow + ['<li>',
  '<div class="col-md-1">' + item.FirstName + '</div> ',
  '<div class="col-md-1 ">' + item.LastName + '</div> '
  '<div class="col-md-1 ">' + item.Country+ '</div>
  '<div class="col-md-1 ">' + item.Id + '</div> '
  '<div class="col-md-1 ">' + $filter('date')(item.BirthDate, 'dd-MMM-yyyy') + '</div> '
  '</li>'].join('');
});

4、Логика форматирования списка

Как только значение collectionObject было присвоено другой переменной, необходимо определить таблицу для отображения данных.

5、Как получить время назначения CollectionObject

Angular отслеживает изменения значения переменной $scope, и как только значение изменяется, $watch вызывается, поэтому логика присваивания CollectionObject должна быть поместена в $watch переменной $scope.

Код如下:

$scope.$watch($scope.object, function (oldValue, newValue) { 
})

Иначе говоря, когда мы выполняем операцию присваивания, Angular обрабатывает это событие и форматирует содержимое списка.

$scope.$watch('collectionObject', function (oldValue, newValue) {
 var tableRow = "";
 angular.forEach($scope.collectionObject, function (item) {
  tableRow = tableRow + ['<li>',
  '<div class="col-md-1">' + item.FirstName + '</div> ',
  '<div class="col-md-1 ">' + item.LastName + '</div> '
  '<div class="col-md-1 ">' + item.State + '</div> '
  '<div class="col-md-1 ">' + item.Id + '</div> '
  '<div class="col-md-1 ">' + $filter('date')(item.BirthDate, 'dd-MMM-yyyy') + '</div> '
  '</li>'].join('');
 });
})

Далее содержимое будет отрисовываться в таблице控件, то есть в HTML <DIV> теге repeater-alternative.
Сначала необходимо понять механизм Directive в Angular, просто говоря, мы указываем Angular, что при обнаружении указанного переменного начинаем выполнять的操作 на заднем плане.

var userDirectives = angular.module([]);
userDirectives.directive('DOMElementFound', function () {
 return {
  replace: true,
  link: function ($scope, $elem, attrs) {
     //Обработка на заднем плане
 }
});

Мы уведомим Angular, что при обнаружении элемента "repeater-alternative" данные будут отрисованы в строке списка.

Код如下:

var userDirectives = angular.module([]);
userDirectives.directive('repeaterAlternative', function () {
 return {
  replace : true,
  link: function ($scope, $elem, attrs) {
   $scope.$watch('collectionObject', function (oldValue, newValue) {
    var tableRow = "";
    angular.forEach($scope.collectionObject, function (item) {
     tableRow = tableRow + ['<li>',
         '<div class="col-md-1">' + item.FirstName + '</div> ',
         '<div class="col-md-1 ">' + item.LastName + '</div> '
         '<div class="col-md-1 ">' + item.State + '</div> '
         '<div class="col-md-1 ">' + item.Id + '</div> '
         '<div class="col-md-1 ">' + $filter('date')(item.BirthDate, 'dd-MMM-yyyy') + '</div> '
         '</li>'].join('');
    });
    //Если Internet Explorer является вашим основным браузером, рекомендуется использовать innerHTML для повышения производительности
    $elem.context.innerHTML = tableRow;
    //Если Internet Explorer не является вашим основным браузером, достаточно просто добавить содержимое к элементу.
    //elem.append(tableRow);
   });
  }
 }
});

Обобщение

В этой статье основное внимание уделяется имитации работы и логики ng-repeat, но только для статического контента, поэтому результат вывода совпадает с результатом вызова ng-repeat, но рендеринг быстрее, так как этот метод имеет только один способ привязки данных и небольшое количество $watch. Это и есть все содержимое этой статьи, надеюсь, что информация из нее поможет вам в изучении или работе. Если у вас есть вопросы, вы можете оставить комментарий для обсуждения.

Основной учебник
Вам может понравиться