Est-il possible de mettre en place un $watch
sur un tableau d'objets à l'intérieur d'un service (j'aimerais que la fonction $watch
pour être à l'intérieur du service) ?
Réponses
Trop de publicités?Vous pouvez ajouter n'importe quelle expression à l'ensemble des montres en injectant l'élément $rootScope
et en utilisant une fonction comme premier argument de la $watch
méthode. Pseudo-code :
$rootScope.$watch(function() {
return //value to be watched;
}, function watchCallback(newValue, oldValue) {
//react on value change here
});
N'oubliez pas le troisième argument, booléen, de la fonction $watch
méthode. Vous devez spécifier true
si vous souhaitez surveiller en profondeur les modifications d'un objet entier.
De par leur nature même, les services s'apparentent à des classes et à des méthodes domestiques. Vous pouvez mettre en place une méthode que vous appelez depuis votre contrôleur, dont l'argument est le champ d'application et qui applique une expression de surveillance :
app.service('myservice',function(){
this.listen = function($scope) {
$scope.$watch(function(){return someScopeValue},function(){
//$scope.dosomestuff();
});
}
});
//your controller
function myCtrl($scope,myservice) {
$scope.listen = function() {
myservice.listen($scope);
}
//call your method
$scope.listen();
}
mise à jour : Si vous essayez de surveiller une variable locale privée à l'intérieur d'un service, voir la réponse acceptée en utilisant $rootScope. Si vous essayez de $watch une variable $scope à l'intérieur d'une portée locale, la réponse ci-dessus est votre meilleur choix. Il s'agit de deux choses très différentes.
Pouvez-vous préciser ce que vous souhaitez obtenir ? Si je comprends bien, vous obtenez un tableau d'objets du serveur en tant que modèle. Ce n'est donc pas clair :
- Voulez-vous vérifier si certains objets du tableau ont été modifiés ? (peut-être depuis le dernier appel au serveur dans le cas d'une mise en commun récurrente) ? récurrent) ?
- Souhaitez-vous vérifier si certains objets du tableau ont été modifiés par l'utilisateur au moyen d'éléments de contrôle frontaux ?
Dans le cas 1, vous n'avez pas vraiment besoin d'utiliser $watch (ou plutôt $watchCollection) mais vous devriez itérer à travers le tableau que vous avez reçu du serveur et vérifier les changements (de la même manière que $watchColleciton le ferait). Dans le cas où l'objet est différent de celui que vous détenez actuellement, vous appelez object.$save() sur cet élément.
Dans le cas 2, utilisez $watchCollection() sur le $scope passé en paramètre à votre fonction de service ou utilisez $rootScope si vous conservez votre tableau dans le $rootScope.
Je peux vous fournir un code réel si vous souhaitez clarifier les scénarios.
Je viens d'être confronté à une situation où j'avais une configuration de montre assez importante sur 2 contrôleurs différents.
Comme je ne voulais pas dupliquer le code, j'ai simplement défini la fonction dans mon service :
angular
.module('invoice')
.factory('invoiceState', function () {
var invoice = {
client_info: {
lastname: "",
firstname: "",
email: "",
phone: "",
id_client: "",
...
}
}
invoice.watchAccommodation = function (newVal, oldVal) {
var accommodation = newVal;
//Whatever you would normally have in your watch function
}
Il me suffit ensuite d'appeler cette fonction dans la veille de n'importe quel contrôleur dans lequel j'ai injecté le service
function NewInvoiceCtrl(invoiceState) {
$scope.$watch('invoice.accommodation',invoiceState.watchAccommodation, true);
}
Je n'ai pas beaucoup d'expérience avec AngularJS donc je ne peux pas vraiment aller dans les aspects de performance de cette approche mais cela fonctionne ;).