Hvad er $scope i AngularJS? Vejledning med eksempel

โšก Smart opsummering

$Scope i AngularJS er det indbyggede objekt, der binder en controller til dens view. Denne side forklarer oprettelse af scopes, funktionsfunktioner, forรฆldre- og bรธrnehierarki, forskellen fra $rootScope, og hvordan digest-cyklusser opdaterer bindinger.

  • ๐Ÿ”— Bindende rolle: $scope overfรธrer medlemsvariabler fra en controller til viewet, sรฅ skabeloner gengiver data uden at berรธre DOM'en direkte.
  • ๐Ÿ‡ง๐Ÿ‡ท Adfรฆrdsfunktioner: Vedhรฆft funktioner til $scope, nรฅr visningen skal reagere pรฅ klik, รฆndringer i input eller andre brugerhรฆndelser.
  • ???? Omfangshierarki: Direktiver som ng-controller og ng-repeat opretter underordnede scopes, der afspejler applikationens DOM-trรฆ.
  • ๐ŸŒ $rootScope rรฆkkevidde: Der findes รฉn $rootScope pr. applikation og opfรธrer sig som et globalt objekt, som alle underordnede scopes kan lรฆse.
  • ๐Ÿ” Fordรธjelsescyklus: $watch registrerer lyttere, $apply indtaster AngularJS-udfรธrelseskonteksten, og $digest sammenligner vรฆrdier, indtil modellen stabiliserer sig.
  • ๐Ÿš€ Prรฆstationsvane: Hold watch-udtryk billige, undgรฅ DOM-adgang i dem og kald $destroy pรฅ scopes, der ikke lรฆngere er nรธdvendige.

Hvad er $Scope i AngularJS

Hvad er $scope i AngularJS?

$scope i AngularJS er et indbygget objekt, som grundlรฆggende binder "controlleren" og "visningen". Man kan definere medlemsvariabler i omfanget i controlleren, som derefter kan tilgรฅs af visningen.

Hver controller i en AngularJS Applikationen modtager sin egen $scope-instans via afhรฆngighedsinjektion. Alt, hvad du knytter til det objekt, bliver synligt for den skabelon, som controlleren styrer, sรฅ $scope fungerer som den delte datamodel, der sidder mellem din JavaScriptlogik og din HTML-markup.

Overvej eksemplet nedenfor:

$scope i AngularJS

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

Code Forklaring:

  1. Navnet pรฅ modulet er "app"
  2. Navnet pรฅ controlleren er "HelloWorldCtrl"
  3. Scope-objekt er hovedobjektet, som bruges til at videregive information fra controlleren til visningen.
  4. Medlemsvariabel tilfรธjet til scope-objekt

โš ๏ธ Syntaksadvarsel: .controller() Metoden tager to argumenter, controllernavnet og fabriksfunktionen, sรฅ et komma er pรฅkrรฆvet mellem 'HelloWorldCtrl' og function($scope)Hvis kommaet udelades, skabes der en Uncaught SyntaxError fรธr AngularJS nogensinde bootstrappede.

En enkelt controller og en enkelt visning er kun halvdelen af โ€‹โ€‹billedet. Virkelige applikationer indlejrer controllere, gentager lister og genbruger widgets, hvilket betyder, at der findes flere scopes pรฅ รฉn gang.

Hvordan omfangshierarki og arv fungerer i AngularJS

Hver AngularJS-applikation har prรฆcis รฉt rodscope og kan have et hvilket som helst antal underordnede scopes. Direktiver opretter disse underordnede scopes og knytter dem til det DOM-element, de dekorerer, sรฅ scope-trรฆet afspejler strukturen pรฅ den gengivne side.

Nรฅr AngularJS evaluerer et udtryk som f.eks. {{siteName}}, sรธger den fรธrst efter den egenskab pรฅ det scope, der er knyttet til elementet. Hvis egenskaben mangler, flyttes opslaget til det overordnede scope og fortsรฆtter med at klatre, indtil det nรฅr rodscopet. JavaScriptudviklere kender denne adfรฆrd som prototypisk arv, og underordnede scopes arver fra deres forรฆldre pรฅ prรฆcis den mรฅde.

Eksemplet nedenfor indlejrer รฉn controller i en anden, sรฅ du kan se nedarvning ske.

<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 Forklaring:

  1. ParentCtrl definerer siteName pรฅ sit eget omfang.
  2. ChildCtrl definerer aldrig siteName, men den indre div udskriver stadig Guru99 fordi opslaget gรฅr op til det overordnede omfang.
  3. lesson lever kun pรฅ det underordnede scope, sรฅ den overordnede div kan ikke lรฆse den.

Hvilke direktiver skaber et nyt anvendelsesomrรฅde?

  • ng-controller: opretter et underordnet scope for det element, det er placeret pรฅ.
  • ng-gentagelse: opretter รฉt underordnet omfang pr. iteration, hvilket er grunden til, at hver rรฆkke kan indeholde forskellige vรฆrdier for det samme udtryk.
  • Brugerdefinerede direktiver: kan anmode om et underordnet omfang eller en isolere et omrรฅde, der bevidst ikke arver fra sin overordnede.
  • Komponentdirektiver: noget, der er registreret hos .component() Hjรฆlperen modtager altid et isoleret oscilloskop.

Fordi underordnede scopes lรฆser opad, spekulerer udviklere ofte pรฅ, hvor toppen af โ€‹โ€‹den kรฆde sidder. Det รธverste objekt kaldes $rootScope.

$scope vs. $rootScope: Hvad er forskellen?

AngularJS $rootScope er omfanget for hele applikationen. En applikation kan kun have รฉn $rootScope, og den bruges som en global variabel. Hver $scope er et underordnet omfang, og $rootScope er det overordnede objekt รธverst i trรฆet. Tabellen nedenfor sammenligner de to objekter.

Aspect $omfang $rootScope
Forekomster pr. applikation Mange, รฉn pr. controller eller direktiv til oprettelse af et omfang Prรฆcis รฉn
Oprettet af Direktiver sรฅsom ng-controller og ng-repeat Injektoren under applikations bootstrap
Synlighed Dets eget element og alle efterkommere Hvert omfang i applikationen
Typisk brug Data og adfรฆrd for รฉn visning eller รฉn listerรฆkke Applikationsdรฆkkende vรฆrdier, f.eks. en bruger, der er logget ind
Hovedrisiko Vรฆrdier bliver uopnรฅelige uden for grenen Navnekollisioner og skjult kobling, som globale variabler

Brug $rootScope sparsomt. Alt, der placeres der, forbliver aktivt for hele applikationen og kan lรฆses overalt, sรฅ en delt tjeneste er normalt et sikrere hjem for global tilstand. Den officielle $rootScope-reference viser den fulde API.

At vide, hvor data befinder sig, er den ene halvdel af jobbet. Den anden halvdel er at lรฆre brugeren, hvordan man reagerer, nรฅr brugeren gรธr noget.

Opsรฆtning eller tilfรธjelse af adfรฆrd i AngularJS

For at reagere pรฅ hรฆndelser eller udfรธre en form for beregning/behandling i visningen, skal vi angive adfรฆrd til scopet.

Adfรฆrd fรธjes til scope-objekter for at reagere pรฅ specifikke hรฆndelser, der kan udlรธses af visningen. Nรฅr adfรฆrden er defineret i controlleren, kan den tilgรฅs af visningen.

Lad os se pรฅ et eksempel pรฅ, hvordan vi kan opnรฅ dette.

Opsรฆtning eller tilfรธjelse af adfรฆrd

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

  1. Vi opretter en adfรฆrd kaldet "fuldt navn". Denne adfรฆrd er en funktion, som accepterer 2 parametre (fornavn, efternavn).
  2. Funktionen returnerer derefter sammenkรฆdningen af โ€‹โ€‹disse 2 parametre.
  3. I visningen kalder vi adfรฆrden og sender 2 vรฆrdier af "Guru" og "99", som sendes som parametre til adfรฆrden.

Hvis kommandoen udfรธres med succes, vil fรธlgende output blive vist, nรฅr du kรธrer din kode i browseren.

Output:

Opsรฆtning eller tilfรธjelse af adfรฆrd

I browseren vil du se en sammenkรฆdning af begge vรฆrdier af Guru & 99, som blev videregivet til adfรฆrden i controller.

Bindinger som den ovenfor opdateres af sig selv, og det maskineri, der fรฅr det til at ske, er vรฆrd at forstรฅ, fรธr en applikation vokser sig stor.

Hvorfor Scope Watchers og Digest Cycle er vigtige

AngularJS holder visningen i trit med scopet gennem dirty checking snarere end gennem รฆndringshรฆndelser. Tre scope-API'er styrer denne proces:

  • $ur: registrerer en lytter for et udtryk. Interpolationer som f.eks. {{fullName}} Registrer dine observatรธrer under skabelontilknytning.
  • $anvend: gรฅr ind i AngularJS-eksekveringskonteksten, evaluerer din kode og udlรธser derefter et digest. Det er kun nรธdvendigt i brugerdefinerede event-callbacks eller callbacks fra tredjepartsbiblioteker, fordi indbyggede direktiver allerede kalder det.
  • $digest: gennemgรฅr hver observatรธr pรฅ $rootScope og dens undergrupper, sammenligner den aktuelle vรฆrdi med den forrige, og gentager, indtil modellen holder op med at รฆndre sig.

Da et digest kan kรธre flere gennemlรธb, skal overvรฅgningsudtryk forblive billige. Undgรฅ DOM-adgang i dem, da lรฆsning af DOM'en er flere stรธrrelsesordener langsommere end lรฆsning af en JavaScript-egenskab.

Dybdeobservation pรฅvirker ogsรฅ prisen. At observere via reference er hurtigst og bemรฆrker kun, nรฅr hele vรฆrdien er erstattet. $watchCollection bemรฆrker elementer tilfรธjet, fjernet eller omarrangeret i et array eller objekt. Observation efter vรฆrdi gennemgรฅr en indlejret struktur pรฅ hver digest og er den dyreste lรธsning, sรฅ grib efter den sidst.

Ofte Stillede Spรธrgsmรฅl

Et isolat-scope arver ikke prototypisk fra sin overordnede. Komponentdirektiver bygget med .component()-hjรฆlperen modtager altid en, som holder genbrugelige widgets uafhรฆngige af den omgivende controller og blokerer utilsigtet lรฆsning af overordnede egenskaber.

$emit sender en scope-hรฆndelse opad gennem forรฆldre-scoper mod $rootScope, mens $broadcast sender den nedad til alle underordnede scoper. Begge modtages med $on. Brug $broadcast sparsomt, da den besรธger alle underordnede scoper.

Kald scope.$destroy(), nรฅr et underordnet scope ikke lรฆngere er nรธdvendigt. Det stopper udbredelsen af โ€‹โ€‹digest i scopet og lader garbage collector'en genvinde sine modeller. Afregistrer ogsรฅ manuelle watchers ved at kalde den funktion, som $watch returnerer.

Assistenter som f.eks. GitHub Copilot producerer hurtigt standardtekst for omfang, men de udsender stadig fejl, sรฅsom et manglende komma i en controllerregistrering. Kontroller hvert genererede kodestykke mod den officielle Dokumentation af AngularJS-omrรฅdet.

AI-assistenter knytter $scope-egenskaber til komponentklassefelter og omskriver $watch-logik som signaler eller RxJS-strรธmme. Par dem med den officielle Vinkelforskydning dokumentation og kรธre enhedstests, fordi genererede konverteringer ofte overser opslag i nedarvede omfang.

Opsummer dette indlรฆg med: