web-dev-qa-db-fra.com

Passage de la portée actuelle à un service AngularJS

Est-il correct de passer le "courant" $scope à un service AngularJS?

Je suis dans la situation où j'ai un service $ sachant qu'il est consommé par un seul contrôleur et j'aimerais avoir une référence à la portée du contrôleur dans les méthodes du service $ elles-mêmes.

Est-ce philosophiquement correct?

Ou je ferais mieux de diffuser les événements sur le $ rootScope, puis de les faire écouter par mon contrôleur?

106
S.C.

Pour que le contrôleur sache qu'un événement asynchrone se produit, utilisez promesses angulaires .

Pour provoquer le $apply, vous n'avez pas besoin de la portée, vous pouvez appeler $rootScope.$apply, car il n'y a pas de différence à l'appeler dans une portée spécifique ou à la racine.

En ce qui concerne la lecture variable, il serait préférable que vous receviez des paramètres. Mais vous pouvez également le lire à partir d'une portée en tant que paramètre d'objet, mais j'utiliserais un paramètre qui rendrait l'interface de service beaucoup plus claire.

67
Caio Cunha

Je dirais que si votre fonctionnalité est spécifique à un seul contrôleur, vous n’avez pas besoin d’un service.

Les tâches des contrôleurs consistent à manipuler le modèle spécifique, tandis qu'un service doit traiter des tâches globales. Je préférerais m'en tenir à ce paradigme plutôt que de mélanger les choses.

C'est ce que disent les docs

Service

Les services angulaires sont des singletons qui exécutent des tâches spécifiques communes aux applications Web.

contrôleur

Dans Angular, un contrôleur est une fonction JavaScript (type/classe) utilisée pour augmenter les instances de angular Scope, en excluant la portée racine.

PS: En dehors de cela, si vous avez besoin de digérer, vous pouvez également injecter $ rootScope dans votre service.

15
F Lekschas

Oui. Vous pouvez passer le $ scope au service lorsque vous l'initialisez. Dans le constructeur de service, vous pouvez affecter l'étendue à quelque chose comme ceci._scope, puis référencer l'étendue au sein du service!

angular.module('blah').controller('BlahCtrl', function($scope, BlahService) {

    $scope.someVar = 4;

    $scope.blahService = new blahService($scope);

});

angular.module('blah').factory('blahService', function() {

    //constructor
    function blahService(scope) {
        this._scope = scope;

        this._someFunction()
    }

    //wherever you'd reference the scope
    blahService.prototype._someFunction = function() {

        this._scope['someVar'] = 5;

    }

    return blahService;

});
9
user12121234

Je pense personnellement que passer $scope À un service est une mauvaise idée , car il crée une sorte de référence circulaire: le contrôleur dépend du Le service et le service dépendent de la portée du contrôleur.

En plus d'être source de confusion en termes de relations, des choses comme celle-ci finissent par gêner le ramasse-miettes.

Mon approche préférée est de mettre un objet de domaine dans la portée du contrôleur et de le transmettre au service. Ainsi, le service fonctionne, qu'il soit utilisé dans un contrôleur ou dans un autre service à l'avenir.

Par exemple, si le service est supposé pousser et extraire des éléments d'un tableau errors, mon code sera:

var errors = [];
$scope.errors = errors;
$scope.myService = new MyService(errors);

Le service interagit ensuite avec le contrôleur en opérant sur errors. Bien sûr, je dois faire attention de ne jamais effacer toute la référence de tableau, mais au bout du compte, c'est une préoccupation générale du JS.

Je ne voudrais jamais utiliser la diffusion, $apply Et/ou des choses similaires, car à mon avis, les bonnes pratiques OO seront toujours plus efficaces que la magie angulaire.

6
Marco Faustinelli