Comment s'abonner lorsque la propriété change en utilisant la syntaxe controller as
?
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>
Il suffit de lier le contexte pertinent.
$scope.$watch(angular.bind(this, function () {
return this.name;
}), function (newVal) {
console.log('Name changed to ' + newVal);
});
Exemple: http://jsbin.com/yinadoce/1/edit
UPDATE:
La réponse de Bogdan Gersak est en fait une sorte d'équivalent, les deux réponses tentent de lier this
avec le bon contexte. Cependant, j'ai trouvé sa réponse plus propre.
Cela dit, vous devez avant tout comprendre l'idée sous-jacente qui la sous-tend .
UPDATE 2:
Pour ceux qui utilisent ES6, en utilisant arrow function
, vous obtenez une fonction avec le bon contexte OOTB.
$scope.$watch(() => this.name, function (newVal) {
console.log('Name changed to ' + newVal);
});
Je fais habituellement ceci:
controller('TestCtrl', function ($scope) {
var self = this;
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
$scope.$watch(function () {
return self.name;
},function(value){
console.log(value)
});
});
Vous pouvez utiliser:
$scope.$watch("test.name",function(value){
console.log(value)
});
Cela fonctionne JSFiddle avec votre exemple.
Semblable à utiliser le "test" de "TestCtrl en tant que test", comme décrit dans une autre réponse, vous pouvez attribuer "self" à votre portée:
controller('TestCtrl', function($scope){
var self = this;
$scope.self = self;
self.name = 'max';
self.changeName = function(){
self.name = new Date();
}
$scope.$watch("self.name",function(value){
console.log(value)
});
})
De cette manière, vous n'êtes pas lié au nom spécifié dans le DOM ("TestCtrl as test") et vous évitez également le besoin de .bind (this) à une fonction.
... à utiliser avec le code HTML d'origine spécifié:
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
AngularJs 1.5 supporte le $ ctrl par défaut pour la structure ControllerAs.
$scope.$watch("$ctrl.name", (value) => {
console.log(value)
});
Vous pouvez utiliser $ onChanges angular cycle de vie du composant.
voir la documentation ici: https://docs.angularjs.org/guide/component dans la section Application à base de composants
vous pouvez réellement passer une fonction en tant que premier argument de $ watch ():
app.controller('TestCtrl', function ($scope) {
this.name = 'Max';
// hmmm, a function
$scope.$watch(function () {}, function (value){ console.log(value) });
});
Ce qui signifie que nous pouvons retourner notre référence this.name:
app.controller('TestCtrl', function ($scope) {
this.name = 'Max';
// boom
$scope.$watch(angular.bind(this, function () {
return this.name; // `this` IS the `this` above!!
}), function (value) {
console.log(value);
});
});
Lisez un article intéressant sur le sujet controllerAs https://toddmotto.com/digging-into-angulars-controller-as-syntax/
Écrire une montre $ watch en syntaxe ES6 n’a pas été aussi facile que prévu. Voici ce que vous pouvez faire:
// Assuming
// controllerAs: "ctrl"
// or
// ng-controller="MyCtrl as ctrl"
export class MyCtrl {
constructor ($scope) {
'ngInject';
this.foo = 10;
// Option 1
$scope.$watch('ctrl.foo', this.watchChanges());
// Option 2
$scope.$watch(() => this.foo, this.watchChanges());
}
watchChanges() {
return (newValue, oldValue) => {
console.log('new', newValue);
}
}
}