Cos'è $scope in AngularJS? Tutorial con esempio
⚡ Riepilogo intelligente
In AngularJS, $Scope è l'oggetto integrato che collega un controller alla sua vista. Questa pagina spiega la creazione dello scope, le funzioni di comportamento, la gerarchia padre-figlio, la differenza rispetto a $rootScope e come i cicli di digest aggiornano i binding.
Cos'è $scope in AngularJS?
$ambito in AngularJS è un oggetto integrato che fondamentalmente lega il "controller" e la "vista". È possibile definire variabili membro nell'ambito del controller a cui è quindi possibile accedere dalla vista.
Ogni controller in un AngularJS L'applicazione riceve la propria istanza di $scope tramite dependency injection. Qualunque cosa tu alleghi a quell'oggetto diventa visibile al template governato dal controller, quindi $scope si comporta come il modello di dati condiviso che si trova tra il tuo JavaLogica dello script e markup HTML.
Considera l'esempio seguente:
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code Spiegazione:
- Il nome del modulo è “app”
- Il nome del controller è "HelloWorldCtrl"
- L'oggetto Scope è l'oggetto principale che viene utilizzato per passare le informazioni dal controller alla vista.
- Variabile membro aggiunta all'oggetto ambito
⚠️ Avviso di sintassi: Migliori .controller() Il metodo accetta due argomenti, il nome del controller e la funzione factory, quindi è necessaria una virgola tra 'HelloWorldCtrl' and function($scope). Omettere la virgola genera un errore Uncaught SyntaxError prima ancora che AngularJS si avvii.
Un singolo controller e una singola vista rappresentano solo metà del quadro. Le applicazioni reali annidano i controller, ripetono gli elenchi e riutilizzano i widget, il che significa che esistono più ambiti contemporaneamente.
Come funzionano la gerarchia degli ambiti e l'ereditarietà in AngularJS
Ogni applicazione AngularJS ha esattamente uno scope radice e può avere un numero qualsiasi di scope figli. Le direttive creano questi scope figli e li collegano all'elemento DOM che decorano, in modo che l'albero degli scope rispecchi la struttura della pagina renderizzata.
Quando AngularJS valuta un'espressione come {{siteName}}Innanzitutto, cerca quella proprietà nello scope associato all'elemento. Se la proprietà non è presente, la ricerca si sposta allo scope padre e continua a risalire fino a raggiungere lo scope radice. JavaGli sviluppatori di script conoscono questo comportamento come ereditarietà prototipale, e gli ambiti figli ereditano dai loro genitori esattamente in questo modo.
L'esempio seguente annida un controller all'interno di un altro, permettendoti di osservare il funzionamento dell'ereditarietà.
<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 Spiegazione:
ParentCtrldefiniscesiteNamenel suo ambito di applicazione.ChildCtrlnon definisce maisiteName, tuttavia il div interno viene ancora stampato Guru99 perché la ricerca risale fino all'ambito padre.lessonrisiede solo nell'ambito figlio, quindi il div padre non può leggerlo.
Quali direttive creano un nuovo ambito?
- ng-controller: crea un ambito figlio per l'elemento su cui viene posizionato.
- ng-repeat: crea un ambito figlio per iterazione, motivo per cui ogni riga può contenere valori diversi per la stessa espressione.
- Direttive personalizzate: può richiedere un ambito figlio, o un isolato ambito che deliberatamente non eredita dal suo genitore.
- Direttive dei componenti: qualsiasi cosa registrata con il
.component()L'helper riceve sempre un ambito isolato.
Poiché gli ambiti figli leggono verso l'alto, gli sviluppatori spesso si chiedono dove si trovi il vertice di questa catena. L'oggetto di livello superiore si chiama $rootScope.
$scope vs $rootScope: qual è la differenza?
AngularJS $rootScope $rootScope rappresenta l'ambito dell'intera applicazione. Un'applicazione può avere un solo $rootScope, che viene utilizzato come una variabile globale. Ogni $scope è un ambito figlio, mentre $rootScope è l'ambito padre, in cima all'albero. La tabella seguente confronta i due oggetti.
| Aspetto | $scope | $rootScope |
|---|---|---|
| Istanze per applicazione | Molteplici, una per ogni controller o direttiva di creazione dell'ambito. | Esattamente uno |
| Creato da | Direttive come ng-controller e ng-repeat | L'iniettore durante l'avvio dell'applicazione |
| Visibilità | Il suo elemento proprio e tutti i suoi discendenti | Ogni ambito nell'applicazione |
| Utilizzo tipico | Dati e comportamento per una vista o una riga di elenco | valori a livello di applicazione, come ad esempio un utente connesso |
| Rischio principale | I valori diventano irraggiungibili al di fuori della filiale | Conflitti di nomi e accoppiamento nascosto, come le variabili globali |
Utilizzare $rootScope con parsimonia. Tutto ciò che viene inserito lì rimane valido per l'intera applicazione ed è leggibile ovunque, quindi un servizio condiviso è solitamente un luogo più sicuro per lo stato globale. L'ufficiale Riferimento $rootScope Elenca l'API completa.
Sapere dove risiedono i dati è metà del lavoro. L'altra metà consiste nell'insegnare allo scope come reagire quando l'utente compie un'azione.
Configurazione o aggiunta di comportamenti in AngularJS
Per reagire agli eventi o eseguire qualche tipo di calcolo/elaborazione nella View, dobbiamo fornire un comportamento all'ambito.
I comportamenti vengono aggiunti agli oggetti ambito per rispondere a eventi specifici che possono essere attivati dalla vista. Una volta definito il comportamento nel controller, è possibile accedervi dalla vista.
Diamo un'occhiata a un esempio di come possiamo raggiungere questo obiettivo.
<!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 Spiegazione:
- Stiamo creando un comportamento chiamato "fullName". Questo comportamento è una funzione che accetta 2 parametri (firstName,lastname).
- Il comportamento restituisce quindi la concatenazione di questi 2 parametri.
- Nella vista stiamo chiamando il comportamento e passando 2 valori di “Guru" e "99" che vengono passati come parametri al comportamento.
Se il comando viene eseguito correttamente, quando si esegue il codice nel browser verrà visualizzato il seguente output.
Produzione:
Nel browser vedrai una concatenazione di entrambi i valori di Guru e 99 che sono stati trasmessi al comportamento nel controllore.
I binding come quello sopra si aggiornano automaticamente, ed è importante capire il meccanismo che permette questo processo prima che un'applicazione diventi di grandi dimensioni.
Perché Scope Watchers e il ciclo di digestione sono importanti
AngularJS mantiene la vista allineata con lo scope tramite il controllo delle modifiche (dirty checking) anziché tramite eventi di cambiamento. Tre API di scope guidano questo processo:
- $watch: registra un ascoltatore per un'espressione. Interpolazioni come
{{fullName}}registra gli osservatori per te durante il collegamento del modello. - $applica: Entra nel contesto di esecuzione di AngularJS, valuta il codice e quindi avvia un digest. È necessario solo all'interno di callback di eventi personalizzati o callback di librerie di terze parti, perché le direttive integrate lo richiamano già.
- $digest: Il processo esamina ogni osservatore su $rootScope e i suoi figli, confrontando il valore corrente con quello precedente, e si ripete finché il modello non smette di cambiare.
Poiché un digest può eseguire diversi passaggi, le espressioni watch devono rimanere economiche. Evitare l'accesso al DOM al loro interno, poiché la lettura del DOM è di ordini di grandezza più lenta della lettura di un JavaProprietà dello script.
Anche la profondità di monitoraggio influisce sul costo. Il monitoraggio per riferimento è il più veloce e rileva la sostituzione dell'intero valore solo quando questo viene sostituito. $watchCollection Consente di rilevare gli elementi aggiunti, rimossi o riordinati all'interno di un array o di un oggetto. Il monitoraggio per valore attraversa una struttura annidata a ogni digest ed è l'opzione più dispendiosa, quindi è consigliabile utilizzarla per ultima.




