web-dev-qa-db-fra.com

$ regarder à l'intérieur d'un service?

Est-il possible de configurer un $watch sur un tableau d'objets à l'intérieur d'un service (j'aimerais que la déclaration $watch soit elle-même à l'intérieur du service)?

60
Kuba Orlik

Vous pouvez ajouter n'importe quelle expression à l'ensemble de contrôles en injectant le $rootScope et en utilisant une fonction comme premier argument de la méthode $watch. 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 méthode $watch. Vous devez spécifier true si vous souhaitez surveiller en profondeur tout un objet pour y rechercher des modifications.

121

les services, de par leur nature même, sont comme des classes et des méthodes maison. Vous pouvez configurer une méthode que vous appelez depuis votre contrôleur dont l'argument est la portée et applique une expression de contrôle:

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();
}

update: si vous essayez de regarder une variable locale privée à l'intérieur d'un service, consultez la réponse acceptée avec $ rootScope. Si vous essayez de regarder une variable $ scope dans une étendue locale, ceci est votre meilleur pari. Ils réalisent deux choses très différentes.

15
btm1

Pouvez-vous préciser ce que vous voulez réaliser? Si je comprends bien, vous obtenez un tableau d'objets du serveur comme modèle. Alors ce n'est pas clair: 

  1. Voulez-vous vérifier si certains objets du tableau ont été modifiés (Peut-être depuis le dernier appel au serveur si vous effectuez un pooling récurrent)? 
  2. Voulez-vous vérifier si certains objets du tableau ont été modifiés par l'utilisateur via des éléments de contrôle front-end?

Dans le cas 1, vous n'avez pas vraiment besoin d'utiliser $ watch (ou plutôt $ watchCollection), mais vous devez parcourir le tableau que vous avez reçu du serveur et vérifier les modifications (comme ce que ferait $ watchColleciton). Si l'objet est différent de celui que vous possédez actuellement, appelez l'objet. $ Save () sur cet élément.

Dans le cas 2, utilisez $ watchCollection () sur $ scope passé en tant que paramètre à votre fonction de service ou utilisez $ rootScope si vous maintenez votre tableau dans $ rootScope.

Je peux vous fournir un code réel si vous souhaitez clarifier les scénarios. 

0

Hé vient de me trouver dans une situation où j'avais une assez grosse configuration de montre sur 2 contrôleurs différents.

Comme je ne voulais pas dupliquer le code que je viens de définir pour fonctionner 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
        }

Ensuite, je peux simplement appeler cette fonction dans la montre de tout 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, je ne peux donc pas vraiment parler des aspects performance de cette approche, mais cela fonctionne;)

0
Dennis de Best