Co je $scope v AngularJS? Tutoriál s příkladem

⚡ Chytré shrnutí

Objekt $Scope v AngularJS je vestavěný objekt, který váže kontroler k jeho zobrazení (view). Tato stránka vysvětluje vytváření rozsahu (scope), behaviorální funkce, hierarchii rodičovských a podřízených objektů, rozdíl od $rootScope a jak digest cyklicky obnovuje vazby.

  • 🔗 Závazná role: $scope přenáší členské proměnné z kontroleru do zobrazení, takže šablony vykreslují data bez přímého kontaktu s DOM.
  • ⚙️ Funkce chování: Připojte funkce k $scope, když zobrazení potřebuje reagovat na kliknutí, změny vstupu nebo jiné události uživatele.
  • ???? Hierarchie oborů: Direktivy jako ng-controller a ng-repeat vytvářejí podřízené obory, které zrcadlí strom DOM aplikace.
  • ???? Dosah $rootScope: Pro každou aplikaci existuje jeden objekt $rootScope, který se chová jako globální objekt, který je schopen číst každý podřízený obor.
  • 🔍 Cyklus trávení: $watch registruje posluchače, $apply vstupuje do kontextu provádění AngularJS a $digest porovnává hodnoty, dokud se model nestabilizuje.
  • ???? Návyk výkonu: Udržujte watch výrazy levné, vyhněte se přístupu k DOM uvnitř nich a volejte $destroy pro obory, které již nejsou potřeba.

Co je $Scope v AngularJS

Co je $scope v AngularJS?

$scope v AngularJS je vestavěný objekt, který v podstatě spojuje „kontrolér“ a „pohled“. V rámci ovladače lze definovat členské proměnné v rozsahu, ke kterým pak může mít přístup pohled.

Každý řídicí systém v AngularJS Aplikace získává svou vlastní instanci $scope prostřednictvím vkládání závislostí. Cokoli k tomuto objektu připojíte, stane se viditelným pro šablonu, kterou řídí kontroler, takže $scope se chová jako sdílený datový model, který se nachází mezi vaším JavaLogika skriptu a vaše HTML kódování.

Zvažte příklad níže:

$scope v AngularJS

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

Code Vysvětlení:

  1. Název modulu je „app“
  2. Název ovladače je „HelloWorldCtrl“
  3. Objekt rozsahu je hlavním objektem, který se používá k předávání informací z ovladače do pohledu.
  4. Členská proměnná přidána do objektu oboru

⚠️ Syntaktické varování: Jedno .controller() Metoda přijímá dva argumenty, název kontroleru a funkci factory, takže mezi nimi je vyžadována čárka. 'HelloWorldCtrl' a function($scope)Vynechání čárky vyvolá Uncaught SyntaxError ještě předtím, než AngularJS vůbec začal bootstrapovat.

Jeden kontroler a jeden pohled jsou jen polovina výsledku. Reálné aplikace vnořují kontrolery, opakují seznamy a znovu používají widgety, což znamená, že existuje několik oborů najednou.

Jak funguje hierarchie oborů a dědičnost v AngularJS

Každá aplikace AngularJS má přesně jeden kořenový obor působnosti a může mít libovolný počet podřízených oborů. Direktivy vytvářejí tyto podřízené obory a připojují je k elementu DOM, který dekorují, takže strom oborů zrcadlí strukturu vykreslené stránky.

Když AngularJS vyhodnocuje výraz, jako například {{siteName}}, nejprve hledá danou vlastnost v oboru připojeném k elementu. Pokud vlastnost chybí, vyhledávání se přesune do nadřazeného oboru a pokračuje v procházení, dokud nedosáhne kořenového oboru. JavaVývojáři skriptů toto chování znají jako prototypovou dědičnost a podřízené obory dědí od svých rodičů přesně tímto způsobem.

Níže uvedený příklad vnořuje jeden kontroler do druhého, takže můžete sledovat dědičnost.

<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 Vysvětlení:

  1. ParentCtrl definuje siteName ve svém vlastním rozsahu.
  2. ChildCtrl nikdy nedefinuje siteName, ale vnitřní div se stále tiskne Guru99 protože vyhledávání přejde k nadřazenému oboru.
  3. lesson žije pouze v podřízeném oboru, takže nadřazený div jej nemůže číst.

Které směrnice vytvářejí novou oblast působnosti?

  • ng-kontrolér: vytvoří podřízený obor pro element, na který je umístěn.
  • ng-opakování: vytváří jeden podřízený obor na iteraci, a proto každý řádek může obsahovat různé hodnoty pro stejný výraz.
  • Vlastní směrnice: může požádat o podřízený rozsah nebo izolovat obor, který záměrně nedědí od svého rodiče.
  • Direktivy komponent: cokoli registrovaného u .component() Pomocník vždy obdrží izolační rozsah.

Protože podřízené obory čtou směrem nahoru, vývojáři si často kladou otázku, kde se nachází vrchol tohoto řetězce. Tento objekt nejvyšší úrovně se nazývá $rootScope.

$scope vs. $rootScope: Jaký je rozdíl?

AngularJS $rootScope je obor platnosti pro celou aplikaci. Aplikace může mít pouze jeden $rootScope a ten se používá jako globální proměnná. Každý $scope je podřízený obor platnosti a $rootScope je nadřazený objekt na vrcholu stromu. Následující tabulka porovnává tyto dva objekty.

Vzhled $scope $rootScope
Instance na aplikaci Mnoho, jeden na kontroler nebo direktivu vytvářející rozsah Přesně jeden
Vytvořil Směrnice jako ng-controller a ng-repeat Injektor během bootstrapu aplikace
Viditelnost Jeho vlastní prvek a všichni potomci Každý obor v aplikaci
Typické použití Data a chování pro jedno zobrazení nebo jeden řádek seznamu Hodnoty pro celou aplikaci, například přihlášený uživatel
Hlavní riziko Hodnoty se stávají nedosažitelnými mimo větev Kolize názvů a skryté vazby, jako globální proměnné

Používejte $rootScope střídmě. Vše, co je tam umístěno, je uloženo pro celou aplikaci a je čitelné všude, takže sdílená služba je obvykle bezpečnějším domovem pro globální stav. Oficiální Referenční hodnota $rootScope uvádí kompletní API.

Vědět, kde se data nacházejí, je jedna polovina práce. Druhou polovinou je naučit obor, jak reagovat, když uživatel něco udělá.

Nastavení nebo přidání chování v AngularJS

Abychom mohli reagovat na události nebo provést nějaký druh výpočtu/zpracování v pohledu, musíme danému rozsahu poskytnout chování.

Chování se přidávají k objektům rozsahu, aby reagovali na konkrétní události, které mohou být spuštěny pohledem. Jakmile je chování definováno v ovladači, může k němu mít přístup pohled.

Podívejme se na příklad, jak toho můžeme dosáhnout.

Nastavení nebo přidání chování

<!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 Vysvětlení:

  1. Vytváříme chování zvané „fullName“. Toto chování je funkce, která přijímá 2 parametry (jméno, příjmení).
  2. Chování pak vrátí zřetězení těchto 2 parametrů.
  3. V zobrazení voláme chování a předáváme 2 hodnoty „Guru„“ a „99“, které se předávají jako parametry chování.

Pokud je příkaz úspěšně proveden, při spuštění kódu v prohlížeči se zobrazí následující výstup.

Výstup:

Nastavení nebo přidání chování

V prohlížeči uvidíte zřetězení obou hodnot Guru & 99, které byly předány chování v kontrolor.

Vazby, jako je ta výše uvedená, se samy aktualizují a mechanismus, který to umožňuje, stojí za to pochopit, než se aplikace rozroste.

Proč jsou Scope Watchers a Digest Cycle důležité

AngularJS udržuje zobrazení v souladu s rozsahem pomocí kontroly typu „dirty checking“ (nečisté kontroly) namísto událostí změny. Tento proces řídí tři API pro rozsah:

  • Sledujte: registruje posluchače pro výraz. Interpolace jako například {{fullName}} zaregistrovat pro vás pozorovatele během propojování šablon.
  • $platí: vstupuje do kontextu provádění AngularJS, vyhodnocuje váš kód a poté spustí digest. Je potřeba pouze uvnitř vlastních zpětných volání událostí nebo zpětných volání knihoven třetích stran, protože vestavěné direktivy jej již volají.
  • $digest: Prochází každým sledujícím objektem $rootScope a jeho podřízenými objekty, porovnává aktuální hodnotu s předchozí a opakuje, dokud se model nepřestane měnit.

Protože digest může probíhat v několika průchodech, musí být watch výrazy levné. Vyhněte se přístupu k DOM uvnitř nich, protože čtení DOMu je řádově pomalejší než čtení JavaVlastnost skriptu.

Hloubka sledování také ovlivňuje cenu. Sledování podle odkazu je nejrychlejší a všimne si pouze nahrazení celé hodnoty. $watchCollection všímá si položek přidáných, odebraných nebo změněných pořadí uvnitř pole nebo objektu. Sledování podle hodnoty prochází vnořenou strukturou při každém digestování a je nejdražší možností, takže po něm sáhněte až nakonec.

Nejčastější dotazy

Izolovaný obor nedědí prototypicky od svého nadřazeného oboru. Direktivy komponenty vytvořené s pomocnou metodou .component() vždy jeden obdrží, což udržuje opakovaně použitelné widgety nezávislé na okolním kontroleru a blokuje náhodné čtení vlastností nadřazeného oboru.

$emit odesílá událost rozsahu směrem nahoru přes nadřazené rozsahy směrem k $rootScope, zatímco $broadcast ji odesílá směrem dolů do každého podřízeného rozsahu. Oba jsou přijímány s $on. Používejte $broadcast střídmě, protože navštíví každý podřízený rozsah.

Jakmile podřízený obor (scope) již není potřeba, zavolejte funkci scope.$destroy(). Tím se zastaví šíření digestů do oboru a garbage collector umožní zpětné získání modelů. Odregistrujte také manuální watchery voláním funkce, kterou vrací $watch.

Asistenti jako např. GitHub Copilot rychle vytvářejí standardizované kódy rozsahu, ale stále vykazují chyby, jako je například chybějící čárka v registraci řadiče. Každý vygenerovaný úryvek zkontrolujte s oficiálním kódem. Dokumentace rozsahu AngularJS.

Asistenti umělé inteligence mapují vlastnosti $scope na pole třídy komponent a přepisují logiku $watch jako signály nebo RxJS streamy. Spárujte je s oficiálními ANGULAR dokumentace a spouštění jednotkových testů, protože generované konverze často chybí v zděděných vyhledáváních rozsahu.

Shrňte tento příspěvek takto: