Dans la section “Créer des composants” de la page d’accueil d’AngularJS, vous trouverez cet exemple:
controller: function($scope, $element) { var panes = $scope.panes = []; $scope.select = function(pane) { angular.forEach(panes, function(pane) { pane.selected = false; }); pane.selected = true; } this.addPane = function(pane) { if (panes.length == 0) $scope.select(pane); panes.push(pane); } }
Notez comment la méthode select
est ajoutée à $scope
, mais la méthode addPane
est ajoutée à this
. Si je le change en $scope.addPane
, le code se casse.
La documentation dit qu’il y a effectivement une différence, mais elle ne mentionne pas la différence:
Les versions précédentes de Angular (version 1.0 RC précédente) vous permettaient d’utiliser
this
méthode de manière interchangeable avec la méthode$scope
, mais ce n’est plus le cas. À l’intérieur des méthodes définies dans la scope,this
scope et celle de$scope
sont interchangeables (la valeur angular la définit comme$scope
), mais pas dans le constructeur de votre contrôleur.
- Comment définir le focus sur le champ de saisie?
- Comment accéder à la variable $ scope dans la console du navigateur en utilisant AngularJS?
- Quelle est la différence entre ‘@’ et ‘=’ dans la scope de la directive dans AngularJS?
- AngularJS: Service vs fournisseur vs usine
- Quel est le meilleur moyen d’appliquer une classe de manière conditionnelle?
Comment this
et $scope
fonctionnent-ils dans les contrôleurs AngularJS?
“Comment
this
et$scope
fonctionnent-ils dans les contrôleurs AngularJS?”
Réponse courte :
this
this
s’agit du contrôleur. $scope
est appelée, this
s’agit de “l’étendue en vigueur lorsque la fonction a été appelée”. Cela peut (ou peut ne pas être!) Être la $scope
laquelle la fonction est définie. Donc, à l’intérieur de la fonction, this
et $scope
peuvent ne pas être les mêmes. $scope
$scope
associé. $scope
associée. $scope
(et les objects de scope parent, si un inheritance prototypique est en jeu) sont accessibles depuis la vue HTML /. Par exemple, à partir de ng-click
, de 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 est chargée), this
(c’est-à-dire le “contexte de fonction”) est défini sur l’object 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’object contrôleur, pas sur $ scope. Les vues ne peuvent pas voir la fonction addPane – elles ont uniquement access aux fonctions définies sur $ scope. En d’autres termes, dans le HTML, cela ne fonctionnera pas:
won't work
Après l’exécution de la fonction constructeur du contrôleur “tabs”, nous avons les éléments suivants:
La ligne noire en pointillés indique l’inheritance prototypique – une scope d’isolement hérite de manière générique de Scope . (Il n’hérite pas de manière prototypique du champ d’application où la directive a été rencontrée dans le code HTML.)
Maintenant, la fonction de lien de la directive de volet veut communiquer avec la directive tabs (ce qui signifie en réalité qu’elle doit affecter les tabs isoler $ scope d’une certaine manière). Les événements peuvent être utilisés, mais un autre mécanisme consiste à demander à la directive de volet de disposer du contrôleur de tabulation. (Il semble ne pas y avoir de mécanisme pour que la directive de volet require
la scope $ des tabs.)
Donc, cela pose la question suivante: si nous n’avons access qu’au contrôleur des tabs, comment pouvons-nous avoir access aux tabs pour isoler $ scope (ce que nous voulons vraiment)?
Eh bien, la ligne pointillée rouge est la réponse. La “scope” de la fonction addPane () (je fais référence à la scope / les fonctions de JavaScript ici) donne à la fonction l’access aux tabs isoler $ scope. C’est-à-dire que addPane () a access aux “tabs IsolateScope” dans le diagramme ci-dessus en raison d’une fermeture créée lors de la définition de addPane (). (Si nous définissons à la place addPane () sur l’object $ scope des tabs, la directive pane n’aurait pas access à cette fonction et n’aurait donc 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
propriété est définie sur “le $ scope en vigueur où / quand la fonction a été appelée”. Supposons que nous ayons le code HTML suivant:
log "this" and $scope - parent scope log "this" and $scope - child scope
Et le ParentCtrl
(uniquement) a
$scope.logThisAndScope = function() { console.log(this, $scope) }
En cliquant sur le premier lien, vous verrez que this
et $scope
sont identiques, car ” la scope en vigueur lorsque la fonction a été appelée ” correspond à la scope associée à la commande ParentCtrl
.
En cliquant sur le deuxième lien, vous découvrirez que this
et $scope
ne sont pas les mêmes, car ” la scope en vigueur lorsque la fonction a été appelée ” est la scope associée à ChildCtrl
. Donc, ici, this
est défini sur $scope
de ChildCtrl
. Dans la méthode, $scope
est toujours la $scope
du ParentCtrl
.
Violon
J’essaie de ne pas utiliser this
intérieur d’une fonction définie sur $ scope, car cela devient confus pour savoir quelle $ scope est affectée, surtout si l’on considère que ng-repeat, ng-include, ng-switch et directives peuvent créer leurs propres étendues enfants. .
La raison pour laquelle addPane est assigné à cela est à cause de la directive
.
La directive de pane
require: '^tabs'
, qui place l’object contrôleur d’tabs d’une directive parente dans la fonction de lien.
addPane
est assigné à this
pour que la fonction de lien du pane
puisse le voir. Ensuite, dans la fonction de lien du pane
, addPane
est juste une propriété du contrôleur de tabs
, et il ne s’agit que de tabsControllerObject.addPane. La fonction de liaison de la directive de volet peut donc accéder à l’object contrôleur des tabs et donc accéder à la méthode addPane.
J’espère que mes explications sont suffisamment claires. C’est difficile à expliquer.
Je viens de lire une explication assez intéressante sur la différence entre les deux et une préférence croissante pour attacher des modèles au contrôleur et alias le contrôleur pour lier les modèles à la vue. http://toddmotto.com/digging-into-angulars-controller-as-syntax/ est l’article. Il ne le mentionne pas mais lors de la définition de directives, si vous avez besoin de partager quelque chose entre plusieurs directives et que vous ne voulez pas de service (il existe des cas légitimes de services), joignez les données au contrôleur de la directive parente. Le service $ scope fournit beaucoup de choses utiles, $ watch étant la plus évidente, mais si tout ce dont vous avez besoin pour lier des données à la vue, utiliser le contrôleur standard et le contrôleur comme indiqué dans le modèle est préférable.
Je vous recommande de lire le post suivant: AngularJS: “Controller as” ou “$ scope”?
Il décrit très bien les avantages de l’utilisation de “Controller as” pour exposer les variables sur “$ scope”.
Je sais que vous avez posé des questions précises sur les méthodes et non sur les variables, mais je pense qu’il vaut mieux s’en tenir à une technique et s’y conformer.
Donc, à mon avis, en raison du problème de variables abordé dans le post, il est préférable d’utiliser la technique “Controller as” et de l’appliquer aux méthodes.
Dans ce cours ( https://www.codeschool.com/courses/shaping-up-with-angular-js ), ils expliquent comment utiliser “this” et bien d’autres choses.
Si vous ajoutez une méthode au contrôleur via la méthode “this”, vous devez l’appeler dans la vue avec le nom du contrôleur “dot” votre propriété ou méthode.
Par exemple, en utilisant votre contrôleur dans la vue, vous pouvez avoir un code comme celui-ci:
Your first pane is {{aliasOfYourController.panes[0]}}
Les versions précédentes de Angular (version 1.0 RC précédente) vous permettaient d’utiliser cette méthode de manière interchangeable avec la méthode $ scope, mais ce n’est plus le cas. À l’intérieur des méthodes définies dans la scope, cette scope et celle de $ sont interchangeables (la valeur angular la définit comme $ scope), mais pas dans le constructeur de votre contrôleur.
Pour ramener ce comportement (est-ce que quelqu’un sait pourquoi cela a été changé?), Vous pouvez append:
return angular.extend($scope, this);
à la fin de votre fonction de contrôleur (à condition que $ scope ait été injecté dans cette fonction de contrôleur).
Cela a un bon effet d’avoir access à la scope parent via l’object contrôleur que vous pouvez obtenir avec child avec require: '^myParentDirective'
$ scope a un ‘this’ différent du contrôleur ‘this’. Ainsi, si vous placez un console.log (this) dans le contrôleur, il vous donnera un object (controller) et this.addPane () appenda la méthode addPane à l’object Controller. Mais la scope $ a une scope différente et toutes les méthodes de sa scope doivent être accédées par $ scope.methodName (). this.methodName()
dans le contrôleur signifie append des méthodes à l’intérieur de l’object contrôleur. $scope.functionName()
est en HTML et à l’intérieur
$scope.functionName(){ this.name="Name"; //or $scope.myname="myname"//are same}
Collez ce code dans votre éditeur et ouvrez la console pour voir …
this $sope vs controller Comming From $SCOPE :{{firstName}}
Comming from $SCOPE:{{lastName}}
Should Come From Controller:{{nickName}} Blank nickName is because nickName is attached to 'this' of controller.
{{message}}