Comment s'abonner au changement de propriété lors de l'utilisation de la controller as
syntaxe?
controller('TestCtrl', function ($scope) {
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
// not working
$scope.$watch("name",function(value){
console.log(value)
});
});
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
Réponses:
Liez simplement le contexte pertinent.
Exemple: http://jsbin.com/yinadoce/1/edit
METTRE À JOUR:
La réponse de Bogdan Gersak est en fait un peu équivalente, les deux réponses essaient de se lier
this
avec le bon contexte. Cependant, j'ai trouvé sa réponse plus propre.Cela dit, vous devez d'abord et avant tout comprendre l'idée sous-jacente .
MISE À JOUR 2:
Pour ceux qui utilisent ES6, en utilisant
arrow function
vous obtenez une fonction avec le bon contexte OOTB.Exemple
la source
$scope
pour vous est une sorte de service qui fournit ce genre de méthodes.name
dansreturn this.name;
fait référence au nom du contrôleur ou à la propriété "name
" ici?angular.bind
renvoie une fonction avec un contexte borné (arg # 1). Dans notre cas, nous lionsthis
, qui est l'instance du contrôleur, à la fonction (arg # 2), doncthis.name
signifie la propriéténame
de l'instance du contrôleur.Je fais généralement ceci:
la source
$scope.$watch
et l'utilisation de cette fonction pour renvoyer une valeur à partir de la fermeture. Je n'ai pas encore rencontré un autre exemple de cela, mais cela fonctionne et c'est le meilleur. La raison pour laquelle je n'ai pas choisi la réponse ci-dessous (c'est-à-dire$scope.$watch('test.name', function (value) {});
) est que je dois coder en dur ce que j'ai nommé mon contrôleur dans mon modèle ou dans $ stateProvider de ui.router et tout changement dans ce dernier briserait par inadvertance l'observateur.angular.bind
) est de savoir si vous souhaitez lierthis
ou simplement ajouter une autre référence à l'this
intérieur de la clôture. Celles-ci sont fonctionnellement équivalentes et, d'après mon expérience, ce type de choix est souvent un appel subjectif et la question d'une opinion très forte.$scope.$watch( ()=> { return this.name' }, function(){} )
Grosse flèche à la rescousse() => this.name
$scope.$watchCollection
et obtenir lesoldVal, newVal
paramètres?Vous pouvez utiliser:
Cela fonctionne JSFiddle avec votre exemple.
la source
Similaire à l'utilisation du "test" de "TestCtrl as test", comme décrit dans une autre réponse, vous pouvez attribuer "self" votre champ d'application:
De cette façon, vous n'êtes pas lié au nom spécifié dans le DOM ("TestCtrl as test") et vous évitez également de devoir lier (this) à une fonction.
... à utiliser avec le code HTML d'origine spécifié:
la source
$scope
est un service, donc si nous ajoutons$scope.self = this
, puis dans un autre contrôleur si nous faisons la même chose, que se passera-t-il?AngularJs 1.5 prend en charge la valeur par défaut $ ctrl pour la structure ControllerAs.
la source
vous pouvez en fait passer une fonction comme premier argument d'un $ watch ():
Ce qui signifie que nous pouvons renvoyer notre référence this.name:
Lisez un article intéressant sur ControllerAs topic https://toddmotto.com/digging-into-angulars-controller-as-syntax/
la source
Vous pouvez utiliser le cycle de vie des composants angulaires $ onChanges .
voir la documentation ici: https://docs.angularjs.org/guide/component sous la section Application basée sur les composants
la source
Écrire une $ watch dans la syntaxe ES6 n'a pas été aussi facile que je m'y attendais. Voici ce que vous pouvez faire:
la source
REMARQUE : cela ne fonctionne pas lorsque View et Controller sont couplés dans une route ou via un objet de définition de directive. Ce qui est montré ci-dessous ne fonctionne que lorsqu'il y a un "SomeController as SomeCtrl" dans le HTML. Tout comme Mark V. le souligne dans le commentaire ci-dessous, et comme il le dit, il vaut mieux faire comme Bogdan le fait.
J'utilise:
var vm = this;
au début du contrôleur pour me débarrasser du mot «ceci». Ensuite ,vm.name = 'Max';
et dans la montre que jereturn vm.name
. J'utilise le "vm" comme @Bogdan utilise "self". Cette variable, que ce soit "vm" ou "self" est nécessaire car le mot "this" prend un contexte différent à l'intérieur de la fonction. (donc retourner this.name ne fonctionnerait pas) Et oui, vous devez injecter $ scope dans votre belle solution "controller as" afin d'atteindre $ watch. Voir le guide de style de John Papa: https://github.com/johnpapa/angularjs-styleguide#controllersla source
Voici comment faire cela sans $ scope (et $ watch!) Top 5 des erreurs - Abuser de la montre
Si vous utilisez la syntaxe "controller as", il vaut mieux éviter d'utiliser $ scope.
Voici mon code dans JSFiddle . (J'utilise un service pour contenir le nom, sinon l'ensemble des méthodes ES5 Object.defineProperty et get provoquent des appels infinis.
la source