"Come funziona this
e $scope
funziona nei controller AngularJS?"
Risposta breve :
this
- Quando viene chiamata la funzione di costruzione del controller,
this
è il controller.
- Quando
$scope
viene chiamata una funzione definita su un oggetto, this
è "l'ambito attivo quando è stata chiamata la funzione". Questo può (o no!) Essere quello su $scope
cui è definita la funzione. Quindi, all'interno della funzione,this
e $scope
potrebbe non essere la stessa.
$scope
- Ogni controller ha un
$scope
oggetto associato .
- Una funzione controller (costruttore) è responsabile dell'impostazione delle proprietà del modello e delle funzioni / comportamento sui relativi associati
$scope
.
- Solo i metodi definiti su questo
$scope
oggetto (e gli oggetti ambito genitore, se è in gioco l'eredità prototipica) sono accessibili dalla vista HTML /. Ad esempio, da ng-click
, filtri, ecc.
Risposta lunga :
Una funzione controller è una funzione di costruzione JavaScript. Quando viene eseguita la funzione di costruzione (ad esempio, quando viene caricata una vista), this
(ovvero, il "contesto della funzione") viene impostato sull'oggetto controller. Quindi nella funzione di costruzione del controller "tabs", quando viene creata la funzione addPane
this.addPane = function(pane) { ... }
viene creato sull'oggetto controller, non su $ scope. Le viste non possono vedere la funzione addPane: hanno accesso solo alle funzioni definite su $ scope. In altre parole, in HTML, questo non funzionerà:
<a ng-click="addPane(newPane)">won't work</a>
Dopo l'esecuzione della funzione di costruzione del controller "tabs", si ottiene quanto segue:
La linea nera tratteggiata indica l'eredità prototipale - un ambito isolato eredita prototipicamente Scope . (Non eredita prototipicamente dall'ambito in vigore in cui la direttiva è stata rilevata nell'HTML.)
Ora, la funzione di collegamento della direttiva pane vuole comunicare con la direttiva tabs (il che significa davvero che deve influenzare in qualche modo $ scope $ scope). È possibile utilizzare gli eventi, ma un altro meccanismo consiste nell'avere la direttiva riquadro require
nel controller delle schede. (Sembra che non ci sia alcun meccanismo per la direttiva riquadro require
nelle schede $ scope.)
Quindi, questo pone la domanda: se abbiamo solo accesso al controller delle schede, come possiamo accedere alle schede isolare $ scope (che è ciò che vogliamo davvero)?
Bene, la linea tratteggiata rossa è la risposta. L '"ambito" della funzione addPane () (mi riferisco all'ambito / alle chiusure della funzione JavaScript qui) consente alla funzione di accedere alle schede isolare $ scope. Vale a dire, addPane () ha accesso alle "schede IsolateScope" nel diagramma sopra a causa di una chiusura creata quando è stato definito addPane (). (Se invece definissimo addPane () sull'oggetto $ scope tabs, la direttiva pane non avrebbe accesso a questa funzione, e quindi non avrebbe modo di comunicare con le schede $ scope.)
Per rispondere all'altra parte della tua domanda how does $scope work in controllers?
:
All'interno delle funzioni definite su $ scope, this
è impostato su "l'ambito $ in effetti dove / quando è stata chiamata la funzione". Supponiamo di avere il seguente HTML:
<div ng-controller="ParentCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - parent scope
<div ng-controller="ChildCtrl">
<a ng-click="logThisAndScope()">log "this" and $scope</a> - child scope
</div>
</div>
E il ParentCtrl
(Solely) ha
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Fare clic sul primo collegamento mostrerà che this
e $scope
sono gli stessi, poiché " l'ambito ha effetto quando è stata chiamata la funzione " è la portata associato al ParentCtrl
.
Facendo clic sul secondo collegamento si rivelerà this
e non$scope
sono gli stessi, poiché " l'ambito in vigore quando è stata chiamata la funzione " è l'ambito associato al . Quindi qui, è impostato su 's . All'interno del metodo, c'è ancora l' ambito $ s.ChildCtrl
this
ChildCtrl
$scope
$scope
ParentCtrl
Violino
Cerco di non usare this
all'interno di una funzione definita su $ scope, poiché diventa confuso quale $ scope sia interessato, specialmente considerando che ng-repeat, ng-include, ng-switch e direttive possono tutti creare i propri ambiti figlio.