Dyrektywa AngularJS ng-repeat z przykładem

⚡ Inteligentne podsumowanie

Dyrektywa ng-repeat w AngularJS renderuje jedną kopię elementu dla każdego elementu w kolekcji zdefiniowanej w zakresie kontrolera. Zamienia tablicę w listę, tabelę lub dowolny powtarzający się znacznik bez konieczności pisania ręcznej pętli.

  • 🔁 Podstawowe zachowanie: ng-repeat klonuje element hosta raz na każdy element, więc dyrektywa należy do powtarzanego elementu, a nie do jego kontenera.
  • 🏷️ Zmienna pętli: Nazwa przed słowem in staje się lokalnym aliasem bieżącego elementu wewnątrz tego klonu.
  • 🧬 Zakres dziecka: Każda iteracja otrzymuje swój własny zakres podrzędny, dlatego przypisanie prymitywu wewnątrz pętli nie dociera do elementu nadrzędnego.
  • 🔑 tożsamość Tracking: A tracWyrażenie k mówi AngularJS, jak identyfikować elementy, i jest wymagane, gdy kolekcja zawiera powtarzające się wartości.
  • 🔢 Wbudowane zmienne lokalne: Właściwości takie jak $index, $first i $last są dostępne w każdej iteracji w celu numerowania i stylizowania.
  • ⚠️ Status wsparcia: Wsparcie dla AngularJS zakończyło się 31 grudnia 2021 r. i nie będą już do niego dodawane żadne poprawki zabezpieczeń.

Dyrektywa AngularJS ng-repeat

Dyrektywa ng-repeat w AngularJS

ng-powtórz Dyrektywy W AngularJS służy do wyświetlania powtarzających się wartości zdefiniowanych w kontrolerze. Czasami musimy wyświetlić listę elementów w widoku, a ng-repeat renderuje listę zdefiniowaną w kontrolerze na stronie widoku.

⚠️ Uwaga dotycząca wsparcia: Osiągnięto AngularJS koniec życia 31 grudnia 2021 r. i nie otrzymuje żadnych dalszych poprawek ani zabezpieczeń. Poniższa dyrektywa pozostaje aktualna w przypadku utrzymania istniejących aplikacji AngularJS 1.x; w nowoczesnych Angular odpowiednikiem jest *ngFor dyrektywa strukturalna.

Przykład dyrektywy AngularJS ng-repeat

Przyjrzyjmy się przykładowi dyrektywy ng-repeat w AngularJS:

Dyrektywa ng-repeat w 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 Wyjaśnienie:

  1. W kontrolerNajpierw definiujemy tablicę elementów listy, które mają być wyświetlane w widoku. Tutaj tablica nazywa się TopicNames zawiera trzy elementy, każdy będący parą nazwa-wartość.
  2. Tablica jest bezpośrednio przypisana do $scope.TopicNames, co sprawia, że ​​jest on dostępny dla widoku powiązanego z tym kontrolerem.
  3. Tagi HTML <ul> (lista nieuporządkowana) i <li> (element listy) wyświetla elementy. Dyrektywa ng-repeat iteruje po każdym wpisie w tablicy i tpname jest zmienną lokalną przechowującą bieżący element, więc {{tpname.name}} drukuje swoją właściwość name.

⚠️ Poprawka: oryginalne wyjaśnienie mówiło, że tablica została „dodana do zmiennej członkowskiej o nazwie topics„W kodzie nie ma takiej zmiennej — tablica jest przypisywana bezpośrednio do $scope.TopicNames, do której odnosi się widok. Wprowadzenie drugiej nazwy w tym miejscu jest częstą przyczyną pustej listy.

Jeśli kod zostanie wykonany prawidłowo, w przeglądarce zostanie wyświetlony poniższy komunikat.

Dyrektywa ng-repeat w AngularJS

AngularJS Wiele kontrolerów

Wcześniej widzieliśmy pojedynczy kontroler, w którym jedna metoda obsługiwała zarówno dodawanie, jak i podrzędnetracZamiast tego możesz użyć wielu kontrolerów, aby oddzielić logikę w sposób bardziej przejrzysty. Na przykład jeden kontroler może operować na liczbach, a drugi na ciągach znaków.

Przyjrzyjmy się przykładowi definiowania wielu kontrolerów w aplikacji AngularJS.

AngularJS Wiele kontrolerów

<!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 Wyjaśnienie:

  1. Zdefiniowano dwa kontrolery, firstcontroller oraz secondcontrollerKażdy z nich dołącza zmienną do własnej zakres: pname w pierwszym, lname w sekundę.
  2. W widoku drugi kontroler jest zagnieżdżony w pierwszym, a wyrażenie wygląda następująco lname z zakresu wewnętrznego. Ponieważ zagnieżdżony kontroler dziedziczy po swoim kontrolerze nadrzędnym, {{pname}} Tutaj również by się to rozwiązało — dziedziczenie następuje w dół, nigdy w górę.

Jeśli kod zostanie wykonany pomyślnie, tekst drugi kontroler jest wyświetlany.

AngularJS Wiele kontrolerów

Jak korzystać track przez z ng-repeat

Najczęstszym błędem ng-repeat jest błąd Duplicates in a repeater are not allowed. Pojawia się w momencie, gdy kolekcja zawiera tę samą wartość dwa razy, i powoduje całkowite zatrzymanie renderowania listy.

Przyczyną jest tożsamość tracKing. AngularJS potrzebuje stabilnego klucza dla każdego elementu, aby móc ponownie wykorzystywać węzły DOM zamiast przebudowywać je przy każdym skrócie. Domyślnie używa samej wartości elementu, więc dwie identyczne wartości kolidują.

<!-- 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>

Wybór pomiędzy tymi dwiema formami ma większe znaczenie, niż mogłoby się wydawać na pierwszy rzut oka. Tracking by $index Zawsze rozwiązuje błąd, ponieważ pozycja jest z definicji unikalna, ale wiąże każdy węzeł DOM ze slotem, a nie z rekordem. Zmiana kolejności lub filtrowanie kolekcji powoduje ponowne użycie niewłaściwych węzłów, co jest widoczne jako pola wejściowe.ping tekst z poprzedniego wiersza.

Tracking za pomocą prawdziwego identyfikatora, takiego jak topic.id Całkowicie tego unika. AngularJS może śledzić każdy rekord w miarę jego przenoszenia, dzięki czemu zmienia kolejność istniejących węzłów zamiast je niszczyć i odbudowywać. W przypadku długich list jest to również znacznie szybsze, ponieważ ponowne renderowanie obejmuje tylko wiersze, które faktycznie uległy zmianie. Użyj $index tylko dla tablic zwykłych wartości, których kolejność nigdy nie ulega zmianie.

Specjalne właściwości dostępne w ng-repeat

Każda iteracja funkcji ng-repeat udostępnia kilka właściwości tylko do odczytu w swoim własnym zakresie potomnym. Opisują one położenie bieżącego elementu w kolekcji, co obejmuje numerację, style naprzemienne i separatory, bez dodawania żadnego dodatkowego stanu do kontrolera.

Właściwość Typ Wartość:
$index Numer Pozycja bieżącego elementu, zaczynająca się od 0
$first Boolean Prawda tylko dla pierwszego elementu
$last Boolean Prawda tylko dla ostatniego elementu
$middle Boolean Prawda dla każdego elementu, który nie jest ani pierwszy, ani ostatni
$even Boolean Prawda, gdy $index jest parzysty
$odd Boolean Prawda, gdy $index jest nieparzysty

Typowe zastosowanie łączy je z klasą ng dla pasków zebryping, jak w ng-class="{'row-alt': $odd}"lub za pomocą ng-if, aby wyrenderować separator w każdym wierszu oprócz ostatniego, napisanego ng-if="!$last"Wyświetlanie czytelnego dla człowieka numeru wiersza jest proste {{$index + 1}}, ponieważ indeks zaczyna się od zera. Wszystkie sześć właściwości jest automatycznie przeliczanych przy każdej zmianie kolekcji, więc nie ma potrzeby ręcznego przeliczania.

Typowe błędy ng-repeat i jak je naprawić

Większość problemów z ng-repeat wynika z duplikatów wartości, dziedziczenia zakresu lub z umieszczenia dyrektywy na niewłaściwym elemencie. Każdy z poniższych symptomów opisuje jego przyczynę.

  • Duplikaty w repetytorze nie są dozwolone: kolekcja ma powtarzalną wartość. Dodaj track by $indexlub lepiej, track by unikalna nieruchomość.
  • Lista nic nie wnosi: Nazwa w widoku nie pasuje do właściwości w zakresie. Wydrukuj kolekcję za pomocą {{TopicNames}} aby potwierdzić, że dotarło.
  • Każdy element się powtarza, łącznie z opakowaniem: ng-repeat został umieszczony na kontenerze, a nie na elemencie. Przenieś go do <li> or <tr>.
  • Edycja danych wejściowych zmienia niewłaściwy wiersz: lista jest tracked by $index podczas gdy przedmioty są ponownie zamawiane. Track zamiast tego za pomocą stabilnego identyfikatora.
  • Zmiany wewnątrz pętli nie są zachowywane: Każda iteracja ma swój własny zakres potomny, więc zapis do prymitywu tworzy lokalną kopię. Zapis do właściwości obiektu, takiej jak item.done.

FAQ

Tak, używając ng-repeat="(key, value) in myObject"Należy pamiętać, że AngularJS iteruje klucze obiektów w kolejności sortowania, a nie w kolejności wstawiania, więc tablica jest bezpieczniejsza, gdy kolejność ma znaczenie.

Filtry łańcuchowe w wyrażeniu, jak w ng-repeat="t in TopicNames | filter:search | orderBy:'name'"Oryginalna tablica pozostaje nienaruszona; zmienia się jedynie kolejność renderowania i podzbiór.

Tak. AI narzędzia mapują ng-repeat do *ngFor oraz track przez do tracFunkcje kBy. Sprawdź dokładnie filtry, ponieważ Angular celowo usunął wbudowane filtry i potoki orderBy.

Narzędzia AI wykrywają wywołania funkcji wewnątrz wyrażenia powtarzającego, które są ponownie uruchamiane przy każdym skrócie, i brakujące tracKlauzule k by wymuszają pełną przebudowę DOM. Oba te elementy są typowymi przyczynami powolnego działania listy.

Użyj formularza komentarza, ng-repeat-start oraz ng-repeat-end, który powtarza zakres elementów pokrewnych. Ma to znaczenie w tabelach, gdzie dodatkowy div zepsułby kod.

Podsumuj ten post następująco: