"Comment fonctionne this
et $scope
fonctionne dans les contrôleurs AngularJS?"
Réponse courte :
this
- Lorsque la fonction constructeur du contrôleur est appelée,
this
est le contrôleur.
- Lorsqu'une fonction définie sur un
$scope
objet est appelée, this
est la "portée en vigueur au moment de l'appel de la fonction". Il peut s'agir (ou non!) De la $scope
définition de la fonction. Donc, à l'intérieur de la fonction, this
et $scope
peut ne pas être le même.
$scope
- Chaque contrôleur a un
$scope
objet associé .
- Une fonction de contrôleur (constructeur) est chargée de définir les propriétés et les fonctions / le comportement du modèle sur son associé
$scope
.
- Seules les méthodes définies sur cet
$scope
objet (et les objets de portée parent, si l'héritage prototypique est en jeu) sont accessibles à partir du HTML / de la vue. Par exemple, à partir de ng-click
, filtres, etc.
Réponse longue :
Une fonction de contrôleur est une fonction constructeur JavaScript. Lorsque la fonction constructeur s'exécute (par exemple, lorsqu'une vue se charge), this
(c'est-à-dire que le "contexte de fonction") est défini sur l'objet contrôleur. Donc, dans la fonction constructeur du contrôleur "tabs", lorsque la fonction addPane est créée
this.addPane = function(pane) { ... }
il est créé sur l'objet contrôleur, pas sur $ scope. Les vues ne peuvent pas voir la fonction addPane - elles n'ont accès qu'aux fonctions définies sur $ scope. En d'autres termes, dans le HTML, cela ne fonctionnera pas:
<a ng-click="addPane(newPane)">won't work</a>
Après l'exécution de la fonction de constructeur de contrôleur "tabs", nous avons ce qui suit:
La ligne noire en pointillés indique l'héritage prototypique - un oscilloscope isolé hérite de Scope de manière prototypique . (Il n'hérite pas de manière prototypique de la portée en vigueur où la directive a été rencontrée dans le HTML.)
Maintenant, la fonction de lien de la directive volet veut communiquer avec la directive tabs (ce qui signifie vraiment qu'elle doit affecter les onglets isoler $ scope d'une certaine manière). Les événements peuvent être utilisés, mais un autre mécanisme consiste à avoir la directive de volet require
le contrôleur des onglets. (Il ne semble pas y avoir de mécanisme pour la directive de volet dans require
les onglets $ scope.)
Donc, cela pose la question: si nous n'avons accès qu'au contrôleur d'onglets, comment pouvons-nous accéder aux onglets isoler $ scope (ce que nous voulons vraiment)?
Eh bien, la ligne pointillée rouge est la réponse. La "portée" de la fonction addPane () (je fais référence ici à la portée / fermetures de la fonction JavaScript) donne à la fonction l'accès aux onglets isolant $ scope. C'est-à-dire, addPane () a accès aux "onglets IsolateScope" dans le diagramme ci-dessus en raison d'une fermeture qui a été créée lorsque addPane () a été défini. (Si nous définissions plutôt addPane () sur l'objet tabs $ scope, la directive pane n'aurait pas accès à cette fonction, et par conséquent, elle n'aurait aucun moyen de communiquer avec les tabs $ scope.)
Pour répondre à l'autre partie de votre question how does $scope work in controllers?
:
Dans les fonctions définies sur $ scope, this
est défini sur "le $ scope en vigueur où / quand la fonction a été appelée". Supposons que nous ayons le code HTML suivant:
<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>
Et le ParentCtrl
(uniquement) a
$scope.logThisAndScope = function() {
console.log(this, $scope)
}
Cliquer sur le premier lien montrera que this
et $scope
sont les mêmes, puisque " la portée en vigueur lorsque la fonction a été appelée " est la portée associée à la ParentCtrl
.
Cliquer sur le deuxième lien révélera this
et ne$scope
sera pas le même, car " la portée en vigueur lorsque la fonction a été appelée " est la portée associée à la ChildCtrl
. Donc , ici, this
est réglé sur ChildCtrl
« s $scope
. À l'intérieur de la méthode, se $scope
trouve toujours la ParentCtrl
portée de $.
Violon
J'essaie de ne pas utiliser à l' this
intérieur d'une fonction définie sur $ scope, car cela devient déroutant quelle $ scope est affectée, d'autant plus que ng-repeat, ng-include, ng-switch et les directives peuvent tous créer leurs propres étendues enfants.