Czym jest $scope w AngularJS? Samouczek z przykładem

⚡ Inteligentne podsumowanie

$Scope w AngularJS to wbudowany obiekt, który wiąże kontroler z jego widokiem. Ta strona wyjaśnia tworzenie zakresu, funkcje behawioralne, hierarchię obiektów nadrzędnych i podrzędnych, różnicę w stosunku do $rootScope oraz sposób odświeżania powiązań w cyklach digest.

  • 🔗 Rola wiążąca: $scope przenosi zmienne członkowskie z kontrolera do widoku, dzięki czemu szablony renderują dane bez bezpośredniego dotykania DOM.
  • ⚙️ Funkcje behawioralne: Dołącz funkcje do $scope, gdy widok musi reagować na kliknięcia, zmiany danych wejściowych lub inne zdarzenia użytkownika.
  • 🌳 Hierarchia zakresu: Dyrektywy takie jak ng-controller i ng-repeat tworzą zakresy podrzędne, które odzwierciedlają drzewo DOM aplikacji.
  • 🌍 Zasięg $rootScope: Istnieje jeden $rootScope na aplikację i zachowuje się jak obiekt globalny, który może zostać odczytany przez każdy zakres podrzędny.
  • 🔍 Cykl trawienia: $watch rejestruje słuchaczy, $apply wchodzi w kontekst wykonania AngularJS, a $digest porównuje wartości, aż model się ustabilizuje.
  • 🚀 Nawyk wydajnościowy: Staraj się, aby wyrażenia watch były tanie, unikaj dostępu do DOM w ich obrębie i wywołuj $destroy w zakresach, które nie są już potrzebne.

Czym jest $Scope w AngularJS

Co to jest zakres $ w AngularJS?

$zakres w AngularJS jest wbudowanym obiektem, który zasadniczo łączy „kontroler” i „widok”. Można zdefiniować zmienne członkowskie w zakresie w kontrolerze, do których następnie będzie można uzyskać dostęp z widoku.

Każdy kontroler w angularjs Aplikacja otrzymuje własną instancję $scope poprzez wstrzykiwanie zależności. Wszystko, co dołączysz do tego obiektu, staje się widoczne dla szablonu zarządzanego przez kontroler, więc $scope zachowuje się jak współdzielony model danych, który znajduje się między Twoimi JavaLogika skryptu i znaczniki HTML.

Rozważ przykład poniżej:

$zakres w AngularJS

angular.module('app',[]).controller('HelloWorldCtrl',
	function($scope)
	{
		$scope.message = "Hello World"
	});

Code Wyjaśnienie:

  1. Nazwa modułu to „aplikacja”
  2. Nazwa kontrolera to „HelloWorldCtrl”
  3. Obiekt Scope jest głównym obiektem służącym do przekazywania informacji ze sterownika do widoku.
  4. Zmienna członkowska dodana do obiektu zakresu

⚠️ Ostrzeżenie dotyczące składni: .controller() metoda przyjmuje dwa argumenty: nazwę kontrolera i funkcję fabryczną, dlatego wymagany jest przecinek między nimi 'HelloWorldCtrl' oraz function($scope). Pominięcie przecinka powoduje Uncaught SyntaxError zanim AngularJS w ogóle się uruchomił.

Pojedynczy kontroler i pojedynczy widok to tylko połowa sukcesu. Prawdziwe aplikacje wykorzystują kontrolery, powtarzają listy i ponownie wykorzystują widżety, co oznacza, że ​​istnieje wiele zakresów jednocześnie.

Jak działa hierarchia zakresów i dziedziczenie w AngularJS

Każda aplikacja AngularJS ma dokładnie jeden zakres główny i może mieć dowolną liczbę zakresów potomnych. Dyrektywy tworzą te zakresy potomne i dołączają je do elementu DOM, który dekorują, dzięki czemu drzewo zakresów odzwierciedla strukturę renderowanej strony.

Gdy AngularJS ocenia wyrażenie takie jak {{siteName}}Najpierw szuka tej właściwości w zakresie dołączonym do elementu. Jeśli właściwość jest niedostępna, wyszukiwanie przechodzi do zakresu nadrzędnego i kontynuuje wspinaczkę, aż dotrze do zakresu głównego. JavaTwórcy skryptów znają takie zachowanie jako dziedziczenie prototypowe, a zakresy podrzędne dziedziczą po swoich elementach nadrzędnych właśnie w ten sposób.

Poniższy przykład zagnieżdża jeden kontroler w drugim, co pozwala obserwować proces dziedziczenia.

<div ng-app="scopeDemo">
    <div ng-controller="ParentCtrl">
        Parent scope value: {{siteName}}
        <div ng-controller="ChildCtrl">
            Child reads parent value: {{siteName}}
            Child own value: {{lesson}}
        </div>
    </div>
</div>

<script type="text/javascript">
    var app = angular.module("scopeDemo", []);

    app.controller("ParentCtrl", function($scope) {
        $scope.siteName = "Guru99";
    });

    app.controller("ChildCtrl", function($scope) {
        $scope.lesson = "AngularJS Scope";
    });
</script>

Code Wyjaśnienie:

  1. ParentCtrl definiuje siteName według własnego zakresu.
  2. ChildCtrl nigdy nie definiuje siteName, ale wewnętrzny div nadal drukuje Guru99 ponieważ wyszukiwanie sięga zakresu nadrzędnego.
  3. lesson znajduje się tylko w zakresie podrzędnym, więc element nadrzędny div nie może go odczytać.

Które dyrektywy tworzą nowy zakres?

  • kontroler ng: tworzy zakres podrzędny dla elementu, na którym jest umieszczony.
  • ng-repeat: tworzy jeden zakres podrzędny na iterację, dlatego każdy wiersz może przechowywać różne wartości dla tego samego wyrażenia.
  • Dyrektywy niestandardowe: może poprosić o zakres podrzędny lub izolować zakres, który celowo nie dziedziczy po swoim rodzicu.
  • Dyrektywy komponentu: cokolwiek zarejestrowanego w .component() helper zawsze otrzymuje zakres izolowany.

Ponieważ zakresy podrzędne czytają się w górę, programiści często zastanawiają się, gdzie znajduje się szczyt tego łańcucha. Ten obiekt najwyższego poziomu nazywa się $rootScope.

$scope vs $rootScope: jaka jest różnica?

AngularJS $rootScope to zakres całej aplikacji. Aplikacja może mieć tylko jeden $rootScope i jest on używany jak zmienna globalna. Każdy $scope jest zakresem podrzędnym, a $rootScope jest obiektem nadrzędnym na szczycie drzewa. Poniższa tabela porównuje te dwa obiekty.

WYGLĄD $zakres $rootScope
Liczba wystąpień na aplikację Wiele, po jednym na kontroler lub dyrektywę tworzącą zakres Dokładnie jeden
Stworzone przez Dyrektywy takie jak ng-controller i ng-repeat Wtryskiwacz podczas bootstrapu aplikacji
Widoczność Własny element i wszystkie potomne Każdy zakres w aplikacji
Typowe zastosowanie Dane i zachowanie dla jednego widoku lub jednego wiersza listy Wartości obejmujące całą aplikację, takie jak zalogowany użytkownik
Główne ryzyko Wartości stają się nieosiągalne poza oddziałem Kolizje nazw i ukryte sprzężenia, np. zmienne globalne

Używaj $rootScope oszczędnie. Wszystko, co tam jest umieszczone, jest dostępne dla całej aplikacji i można je odczytać z dowolnego miejsca, więc usługa współdzielona jest zazwyczaj bezpieczniejszym miejscem dla stanu globalnego. Oficjalny Odwołanie do $rootScope wyświetla pełną wersję API.

Wiedza o tym, gdzie znajdują się dane, to połowa sukcesu. Drugą połową jest nauczenie oscyloskopu, jak reagować na działania użytkownika.

Konfigurowanie lub dodawanie zachowań w AngularJS

Aby reagować na zdarzenia lub wykonywać jakieś obliczenia/przetwarzanie w widoku, musimy zapewnić zachowanie zakresu.

Zachowania są dodawane do obiektów zakresu, aby reagować na określone zdarzenia, które mogą zostać wyzwolone przez Widok. Po zdefiniowaniu zachowania w kontrolerze można uzyskać do niego dostęp z poziomu widoku.

Spójrzmy na przykład, jak możemy to osiągnąć.

Konfigurowanie lub dodawanie zachowania

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta chrset="UTF 8">
    <title>Guru99</title>     
</head>  
<body ng-app="DemoApp">
<h1> Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<div ng-controller="DemoController">
	{{fullName("Guru","99")}}
</div>
<script type="text/javascript">  
	var app = angular.module("DemoApp", []);
	app.controller("DemoController", function($scope) {
    
    $scope.fullName=function(firstName,lastname){
		return firstName + lastname;
		}
	} );
</script> 

</body>  
</html>

Code Wyjaśnienie:

  1. Tworzymy zachowanie o nazwie „fullName”. To zachowanie jest funkcją, która akceptuje 2 parametry (imię, nazwisko).
  2. Następnie zachowanie zwraca połączenie tych dwóch parametrów.
  3. W widoku wywołujemy zachowanie i przekazujemy 2 wartości „Guru” i „99”, które są przekazywane jako parametry do zachowania.

Jeśli polecenie zostanie wykonane pomyślnie, po uruchomieniu kodu w przeglądarce zostanie wyświetlony następujący komunikat.

Wyjście:

Konfigurowanie lub dodawanie zachowania

W przeglądarce zobaczysz połączenie obu wartości Guru & 99, które zostały przekazane do zachowania w kontroler.

Powiązania takie jak to powyżej odświeżają się same, a mechanizm, który to umożliwia, warto poznać, zanim aplikacja stanie się większa.

Dlaczego obserwatorzy zakresu i cykl Digest są ważni

AngularJS utrzymuje widok w zgodzie z zakresem poprzez sprawdzanie błędów, a nie poprzez zdarzenia zmiany. Proces ten jest sterowany przez trzy interfejsy API zakresu:

  • $watch: rejestruje słuchacza dla wyrażenia. Interpolacje takie jak {{fullName}} zarejestruj dla Ciebie obserwatorów podczas łączenia szablonów.
  • Zastosuj: Wchodzi w kontekst wykonania AngularJS, analizuje kod, a następnie uruchamia skrót. Jest potrzebny tylko w niestandardowych wywołaniach zwrotnych zdarzeń lub wywołaniach zwrotnych bibliotek zewnętrznych, ponieważ wbudowane dyrektywy już go wywołują.
  • Podsumowanie: przechodzi przez każdego obserwatora $rootScope i jego dzieci, porównując bieżącą wartość z poprzednią i powtarzając tę ​​operację, aż model przestanie się zmieniać.

Ponieważ skrót może wykonywać kilka przebiegów, wyrażenia obserwujące muszą być tanie. Unikaj dostępu do DOM w ich obrębie, ponieważ odczyt DOM jest o rzędy wielkości wolniejszy niż odczyt… JavaWłaściwość skryptu.

Głębokość obserwacji również wpływa na koszt. Obserwacja przez odniesienie jest najszybsza i wykrywa tylko moment zastąpienia całej wartości. $watchCollection Zauważa elementy dodane, usunięte lub uporządkowane w tablicy lub obiekcie. Obserwacja według wartości analizuje zagnieżdżoną strukturę przy każdym skrócie i jest najdroższą opcją, więc sięgnij po nią na końcu.

FAQ

Zakres izolowany nie dziedziczy prototypowo po swoim elemencie nadrzędnym. Dyrektywy komponentów zbudowane za pomocą funkcji pomocniczej .component() zawsze otrzymują taki element, co pozwala zachować niezależność widżetów wielokrotnego użytku od otaczającego je kontrolera i blokuje przypadkowe odczyty właściwości elementu nadrzędnego.

$emit wysyła zdarzenie zakresu w górę przez zakresy nadrzędne do $rootScope, podczas gdy $broadcast wysyła je w dół do każdego zakresu podrzędnego. Oba są odbierane z $on. Używaj $broadcast oszczędnie, ponieważ dociera on do każdego zakresu podrzędnego.

Wywołaj scope.$destroy(), gdy zakres potomny nie jest już potrzebny. To zatrzyma propagację digestu do zakresu i pozwoli modułowi zbierającemu śmieci odzyskać jego modele. Wyrejestruj również ręczne obserwatory, wywołując funkcję zwracaną przez $watch.

Asystenci tacy jak Drugi pilot GitHub Szybko generują szablony zakresu, ale nadal generują błędy, takie jak brak przecinka w rejestracji kontrolera. Sprawdź każdy wygenerowany fragment kodu z oficjalnym Dokumentacja zakresu AngularJS.

Asystenci AI mapują właściwości $scope na pola klasy komponentów i przepisują logikę $watch jako sygnały lub strumienie RxJS. Połącz je z oficjalnym Angular dokumentację i uruchamiaj testy jednostkowe, ponieważ generowane konwersje często pomijają dziedziczone wyszukiwania zakresu.

Podsumuj ten post następująco: