AngularJS ng-repeat директива с пример

⚡ Умно обобщение

Директивата ng-repeat в AngularJS рендира едно копие на елемент за всеки елемент в колекция, дефинирана в обхвата на контролера. Тя превръща масив в списък, таблица или всякаква повтаряща се маркировка, без да е необходимо да се пише ръчен цикъл.

  • 🔁 Основно поведение: ng-repeat клонира своя хост елемент веднъж за всеки елемент, така че директивата принадлежи на повтарящия се елемент, а не на неговия контейнер.
  • ???? ️ Променлива в цикъла: Името преди думата in става локален псевдоним за текущия елемент вътре в този клонинг.
  • 🧬 Обхват на детето: Всяка итерация получава свой собствен дъщерен обхват, поради което присвояването на примитив вътре в цикъла не достига до родителя.
  • 🔑 Идентичност Tracking: A tracИзразът k чрез указва на AngularJS как да идентифицира елементи и е необходим, когато колекция съдържа повтарящи се стойности.
  • 🔢 Вградени локални преобразуватели: Свойства като $index, $first и $last са достъпни във всяка итерация за номериране и стилизиране.
  • ⚠️ Състояние на поддръжката: AngularJS достигна края на жизнения си цикъл на 31 декември 2021 г. и не получава допълнителни корекции за сигурност.

Директивата ng-repeat в AngularJS

Директива ng-repeat в AngularJS

- ng-повтаряне Директива В AngularJS се използва за показване на повтарящи се стойности, дефинирани в контролера. Понякога е необходимо да покажем списък с елементи в изгледа и ng-repeat рендира списък, дефиниран в контролера, върху страница на изгледа.

⚠️ Известие за поддръжка: Достигнахме AngularJS край на жизнения цикъл на 31 декември 2021 г. и не получава допълнителни корекции или корекции за сигурност. Директивата по-долу остава точна за поддръжка на съществуващи AngularJS 1.x приложения; в съвременните ъглов еквивалентът е *ngFor структурна директива.

Пример за директива AngularJS ng-repeat

Нека разгледаме пример за директивата ng-repeat в AngularJS:

Директива ng-repeat в AngularJS

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp" ng-controller="DemoController">
    <h1>Topics</h1>
    <ul>
        <li ng-repeat="tpname in TopicNames">
            {{tpname.name}}
        </li>
    </ul>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('DemoController', function($scope) {
        $scope.TopicNames = [
            { name: "What controllers do from Angular's perspective" },
            { name: "Controller Methods" },
            { name: "Building a basic controller" }
        ];
    });
</script>

</body>
</html>

Code Обяснение:

  1. в регулатор, първо дефинираме масива от елементи от списъка, които ще се показват в изгледа. Тук масив, наречен TopicNames съдържа три елемента, всеки от които е двойка име-стойност.
  2. Масивът е присвоен директно на $scope.TopicNames, което го прави достъпен за изгледа, свързан с този контролер.
  3. HTML таговете <ul> (неподреден списък) и <li> (елемент от списъка) показва елементите. Директивата ng-repeat итерира през всеки запис в масива и tpname е локалната променлива, съдържаща текущия елемент, следователно {{tpname.name}} отпечатва свойството му name.

⚠️ Корекция: Първоначалното обяснение гласеше, че масивът е „добавен към членска променлива, наречена topics„. Такава променлива не съществува в кода — масивът се присвоява директно на $scope.TopicNames, което е името, към което се отнася изгледът. Въвеждането на второ име тук е честа причина за празен списък.

Ако кодът е изпълнен успешно, в браузъра се показва следният изход.

Директива ng-repeat в AngularJS

AngularJS множество контролери

По-рано видяхме един контролер, в който един метод обработваше както събиране, така и извличане на данни.tracразделяне на числа. Вместо това можете да използвате множество контролери, за да разделите логиката по-ясно. Например, един контролер може да работи с числа, докато друг - с низове.

Нека разгледаме пример за дефиниране на множество контролери в AngularJS приложение.

AngularJS множество контролери

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Event Registration</title>
</head>
<body>
<h1>Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.8.3/angular.js"></script>

<div ng-app="DemoApp">
    <div ng-controller="firstcontroller">
        <div ng-controller="secondcontroller">
            {{lname}}
        </div>
    </div>
</div>

<script>
    var app = angular.module('DemoApp', []);

    app.controller('firstcontroller', function($scope) {
        $scope.pname = "firstcontroller";
    });

    app.controller('secondcontroller', function($scope) {
        $scope.lname = "secondcontroller";
    });
</script>

</body>
</html>

Code Обяснение:

  1. Дефинирани са два контролера, firstcontroller намлява secondcontrollerВсеки прикрепя променлива към собствената си обхват: pname в първия, lname във втория.
  2. В изгледа вторият контролер е вложен в първия и изразът е lname от вътрешния обхват. Тъй като вложен контролер наследява от своя родител, {{pname}} би разрешило и тук — наследството тече надолу, никога нагоре.

Ако кодът е изпълнен успешно, текстът втори контролер се показва.

AngularJS множество контролери

Как да използваме track от с ng-повторение

Най-често срещаният неуспех при ng-repeat е грешката Duplicates in a repeater are not allowedПоявява се в момента, в който колекцията съдържа една и съща стойност два пъти, и спира изцяло рендирането на списъка.

Причината е идентичността tracкрал. AngularJS се нуждае от стабилен ключ за всеки елемент, за да може да използва повторно DOM възлите, вместо да ги пресъздава при всеки дайджест. По подразбиране използва самата стойност на елемента, така че две еднакви стойности се сблъскват.

<!-- Fails: the value 2 appears twice -->
<li ng-repeat="n in [1, 2, 2, 3]">{{n}}</li>

<!-- Works: position is unique even when values repeat -->
<li ng-repeat="n in [1, 2, 2, 3] track by $index">{{n}}</li>

<!-- Best for records from a server: track by a real identifier -->
<li ng-repeat="topic in TopicNames track by topic.id">{{topic.name}}</li>

Изборът между двете форми е по-важен, отколкото изглежда на пръв поглед. Tracking by $index винаги разрешава грешката, защото позицията е уникална по дефиниция, но свързва всеки DOM възел със слот, а не със запис. Пренареждането или филтрирането на колекцията след това използва повторно грешните възли, което се показва като полета за въвеждане keeping текстът на предишния ред.

Tracking чрез истински идентификатор, като например topic.id избягва това напълно. AngularJS може да следва всеки запис, докато се движи, така че пренарежда съществуващите възли, вместо да ги унищожава и изгражда наново. При дълги списъци това е и значително по-бързо, тъй като повторното рендериране засяга само редовете, които действително са се променили. Използвайте $index само за масиви от обикновени стойности, които никога не се пренареждат.

Специални свойства, налични в ng-repeat

Всяка итерация на ng-repeat предоставя няколко свойства само за четене в собствената си дъщерна област. Те описват къде се намира текущият елемент в колекцията, което обхваща номериране, редуване на стилове и разделители, без да се добавя допълнително състояние към контролера.

Имот Тип Стойност
$index Телефон за връзка: Позиция на текущия елемент, започваща от 0
$first Булева Вярно само за първия елемент
$last Булева Вярно само за последния елемент
$middle Булева Вярно за всеки елемент, който не е нито първи, нито последен
$even Булева Вярно, когато $index е четно
$odd Булева Вярно е, когато $index е нечетно

Типична употреба ги комбинира с ng-class за zebra strips.ping, както е в ng-class="{'row-alt': $odd}"или с ng-if за рендиране на разделител на всеки ред с изключение на последния, написан ng-if="!$last"Показването на номер на ред, който може да се чете от човек, е просто {{$index + 1}}, тъй като индексът е базиран на нула. Всичките шест свойства се преизчисляват автоматично при всяка промяна в колекцията, така че нищо не е необходимо да се преизчислява ръчно.

Често срещани грешки при ng-repeat и как да ги поправим

Повечето проблеми с ng-repeat произтичат от дублиращи се стойности, от наследяване на обхват или от директивата, разположена на грешен елемент. Всеки симптом по-долу посочва причината си.

  • Дубликатите в ретранслатор не са разрешени: колекцията съдържа повтаряща се стойност. Добавете track by $index, или по-добре, track by уникален имот.
  • Списъкът не показва нищо: Името в изгледа не съвпада със свойството в обхвата. Отпечатайте колекцията с {{TopicNames}} за да потвърдя, че е пристигнало.
  • Всеки елемент се повтаря, включително обвивката: ng-repeat беше поставен върху контейнера, а не върху елемента. Преместете го в <li> or <tr>.
  • Редактирането на въведени данни променя грешен ред: списъкът е tracкед от $index докато артикулите се пренареждат. Track със стабилен идентификатор вместо това.
  • Промените вътре в цикъла не се запазват: Всяка итерация има свой собствен дъщерен обхват, така че записването в примитив създава локално копие. Записването в свойство на обект, като например item.done.

Въпроси и Отговори

Да, използвайки ng-repeat="(key, value) in myObject"Обърнете внимание, че AngularJS итерира ключовете на обектите в сортиран ред, а не в реда на вмъкване, така че масивът е по-безопасен, когато последователността е от значение.

Верижни филтри в израза, както е в ng-repeat="t in TopicNames | filter:search | orderBy:'name'"Оригиналният масив е непроменен; променят се само редът на рендиране и подмножеството.

Да. AI инструменти map ng-repeat към *ngFor намлява track от до trackBy функции. Проверете внимателно филтрите, защото Angular умишлено е пропуснал вградения филтър и orderBy каналите.

Инструментите с изкуствен интелект забелязват извиквания на функции в израза за повторение, които се изпълняват повторно при всеки дайджест, и липсват track by клаузи, които налагат пълно преизграждане на DOM. И двете са обичайните причини за бавен списък.

Използвайте формата за коментари, ng-repeat-start намлява ng-repeat-end, който повтаря набор от сродни елементи. Това е важно в таблици, където допълнителен div би нарушил маркировката.

Обобщете тази публикация с: