Vad är $scope i AngularJS? Handledning med exempel

⚡ Smart sammanfattning

$Scope i AngularJS är det inbyggda objektet som binder en kontroller till sin vy. Den här sidan förklarar skapande av scope, beteendefunktioner, föräldra- och barnhierarki, skillnaden från $rootScope och hur digestcykler uppdaterar bindningar.

  • 🔗 Bindande roll: $scope överför medlemsvariabler från en kontroller till vyn, så mallar renderar data utan att vidröra DOM-koden direkt.
  • ⚙️ Beteendefunktioner: Koppla funktioner till $scope när vyn behöver reagera på klick, inmatningsändringar eller andra användarhändelser.
  • ???? Omfattningshierarki: Direktiv som ng-controller och ng-repeat skapar underordnade omfattningar som speglar applikationens DOM-träd.
  • 🌍 $rootScope räckvidd: En $rootScope finns per applikation och beter sig som ett globalt objekt som varje underordnat scope kan läsa.
  • 🔍 Smältningscykel: $watch registrerar lyssnare, $apply går in i AngularJS-exekveringskontexten och $digest jämför värden tills modellen stabiliseras.
  • 🚀 Prestationsvana: Håll bevakningsuttryck billiga, undvik DOM-åtkomst inuti dem och anropa $destroy på scopes som inte längre behövs.

Vad är $Scope i AngularJS

Vad är $scope i AngularJS?

$scope i AngularJS är ett inbyggt objekt som i princip binder ihop "kontrollern" och "vyn". Man kan definiera medlemsvariabler i scopet inom regulatorn som sedan kan nås av vyn.

Varje kontrollant i en AngularJS applikationen får sin egen $scope-instans genom beroendeinjektion. Allt du kopplar till det objektet blir synligt för mallen som styrenheten styr, så $scope beter sig som den delade datamodellen som finns mellan dina JavaSkriptlogik och din HTML-kod.

Tänk på exemplet nedan:

$scope i AngularJS

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

Code Förklaring:

  1. Namnet på modulen är "app"
  2. Kontrollenhetens namn är "HelloWorldCtrl"
  3. Scope-objekt är huvudobjektet som används för att skicka information från regulatorn till vyn.
  4. Medlemsvariabel tillagd till scope-objekt

⚠️ Syntaxvarning: Ocuco-landskapet .controller() Metoden tar två argument, kontrollernamnet och fabriksfunktionen, så ett kommatecken krävs mellan 'HelloWorldCtrl' och function($scope)Om man utelämnar kommatecknet skapas en Uncaught SyntaxError innan AngularJS någonsin startade.

En enda kontroller och en enda vy är bara halva bilden. Verkliga applikationer kapslar kontroller, upprepar listor och återanvänder widgetar, vilket innebär att flera scopes finns samtidigt.

Hur omfattningshierarki och arv fungerar i AngularJS

Varje AngularJS-applikation har exakt ett rotscope och kan ha ett valfritt antal underscopes. Direktiv skapar dessa underscopes och kopplar dem till DOM-elementet de dekorerar, så att scope-trädet speglar strukturen på den renderade sidan.

När AngularJS utvärderar ett uttryck som {{siteName}}, den letar först efter den egenskapen på det scope som är kopplat till elementet. Om egenskapen saknas flyttas sökningen till det överordnade scopet och fortsätter att klättra tills den når rotscopet. JavaSkriptutvecklare känner detta beteende som prototypisk arv, och underordnade omfattningar ärver från sina föräldrar på exakt det sättet.

Exemplet nedan kapslar en kontroller inuti en annan så att du kan se arv 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 Förklaring:

  1. ParentCtrl definierar siteName på sitt eget omfång.
  2. ChildCtrl definierar aldrig siteName, men den inre div:en skrivs fortfarande ut Guru99 eftersom sökningen går upp till det överordnade omfånget.
  3. lesson finns bara på det underordnade omfånget, så den överordnade div-en kan inte läsa den.

Vilka direktiv skapar ett nytt tillämpningsområde?

  • ng-kontroller: skapar ett underordnat scope för elementet det placeras på.
  • ng-upprepa: skapar ett underordnat omfång per iteration, vilket är anledningen till att varje rad kan innehålla olika värden för samma uttryck.
  • Anpassade direktiv: kan begära ett underordnat omfång, eller en isolera omfattning som avsiktligt inte ärver från sin förälder.
  • Komponentdirektiv: något som är registrerat hos .component() Hjälparen får alltid ett isolerat omgångsskop.

Eftersom underordnade omfång läser uppåt undrar utvecklare ofta var toppen av den kedjan sitter. Det objektet på toppnivå kallas $rootScope.

$scope vs $rootScope: Vad är skillnaden?

AngularJS $rootScope är scopet för hela applikationen. En applikation kan bara ha en $rootScope och den används som en global variabel. Varje $scope är ett underscope och $rootScope är föräldern högst upp i trädet. Tabellen nedan jämför de två objekten.

Aspect $omfattning $rootScope
Instanser per applikation Många, en per kontroller eller direktiv som skapar omfattning Exakt en
Skapad av Direktiv som ng-controller och ng-repeat Injektorn under applikationsstart
Sikt Dess eget element och alla ättlingar Varje omfattning i applikationen
Typisk användning Data och beteende för en vy eller en listrad Applikationsomfattande värden, till exempel en inloggad användare
Huvudrisken Värden blir oåtkomliga utanför grenen Namnkollisioner och dold koppling, som globala variabler

Använd $rootScope sparsamt. Allt som placeras där lever kvar för hela applikationen och är läsbart överallt, så en delad tjänst är vanligtvis ett säkrare hem för globala tillstånd. Den officiella $rootScope-referens listar hela API:et.

Att veta var data finns är ena halvan av jobbet. Den andra halvan är att lära operatören hur man ska reagera när användaren gör något.

Konfigurera eller lägga till beteende i AngularJS

För att kunna reagera på händelser eller utföra någon form av beräkning/bearbetning i vyn måste vi tillhandahålla beteende till omfattningen.

Beteenden läggs till i omfångsobjekt för att svara på specifika händelser som kan utlösas av vyn. När beteendet väl har definierats i kontrollern kan det nås av vyn.

Låt oss titta på ett exempel på hur vi kan uppnå detta.

Ställa in eller lägga till Beteende

<!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 Förklaring:

  1. Vi skapar ett beteende som kallas "fullnamn". Detta beteende är en funktion som accepterar 2 parametrar (förnamn, efternamn).
  2. Beteendet returnerar sedan sammankopplingen av dessa 2 parametrar.
  3. I vyn anropar vi beteendet och skickar in två värden för "Guru” och ”99” som skickas som parametrar till beteendet.

Om kommandot exekveras framgångsrikt kommer följande utdata att visas när du kör din kod i webbläsaren.

Produktion:

Ställa in eller lägga till Beteende

I webbläsaren ser du en sammanfogning av båda värdena för Guru & 99 som skickades till beteendet i styrenhet.

Bindningar som den ovan uppdateras av sig själva, och maskineriet bakom det är värt att förstå innan en applikation växer sig stor.

Varför Scope Watchers och Digest Cycle är viktiga

AngularJS håller vyn i takt med scopet genom dirty checking snarare än genom change events. Tre scope-API:er driver den processen:

  • $klocka: registrerar en lyssnare för ett uttryck. Interpoleringar som {{fullName}} registrera tittare åt dig under mallänkning.
  • $ansök: går in i AngularJS-exekveringskontexten, utvärderar din kod och utlöser sedan en sammanfattning. Den behövs bara i anpassade händelseåteranrop eller återanrop till tredjepartsbibliotek, eftersom inbyggda direktiv redan anropar den.
  • $digest: går igenom varje observatör på $rootScope och dess undergrupper, jämför det aktuella värdet med det föregående och upprepar tills modellen slutar ändras.

Eftersom en sammanfattning kan köras flera gånger måste bevakningsuttryck förbli billiga. Undvik DOM-åtkomst inuti dem, eftersom det är flera gånger långsammare att läsa DOM:en än att läsa en. JavaSkriptegenskap.

Klockdjupet påverkar också kostnaden. Att titta med referens är snabbast och märker bara när hela värdet ersätts. $watchCollection noterar objekt som lagts till, tagits bort eller ordnats om i en array eller ett objekt. Att titta efter värde genomsöker en kapslad struktur vid varje sammandrag och är det dyraste alternativet, så välj det sist.

Vanliga frågor

Ett isolat-scope ärver inte prototypiskt från sin förälder. Komponentdirektiv som byggts med .component()-hjälpen får alltid ett, vilket håller återanvändbara widgetar oberoende av den omgivande kontrollanten och blockerar oavsiktliga läsningar av förälderegenskaper.

$emit skickar en scope-händelse uppåt genom överordnade scopes mot $rootScope, medan $broadcast skickar den nedåt till varje underordnat scope. Båda tas emot med $on. Använd $broadcast sparsamt, eftersom den besöker varje underordnat scope.

Anropa scope.$destroy() när ett underordnat scope inte längre behövs. Det stoppar spridningen av digest in i scopet och låter garbage collector återta sina modeller. Avregistrera även manuella watchers genom att anropa funktionen som $watch returnerar.

Assistenter som t.ex. GitHub Copilot producerar standardbeskrivningar för omfång snabbt, men de genererar fortfarande felaktigheter som ett saknat kommatecken i en kontrollregistrering. Kontrollera varje genererat kodavsnitt mot den officiella Dokumentation för AngularJS-omfång.

AI-assistenter mappar $scope-egenskaper till komponentklassfält och skriver om $watch-logik som signaler eller RxJS-strömmar. Koppla ihop dem med den officiella Vinkel dokumentation och köra enhetstester, eftersom genererade konverteringar ofta missar ärvda omfattningssökningar.

Sammanfatta detta inlägg med: