简体   繁体   中英

Why can't I inject my service?

I have the following new service:

var SignatureService = function ($scope) {

    this.announce = function () {
        alert($scope.specificName);
    }
};
SignatureService.$inject = ['$scope'];

This is declared for the app as follows:

MyAngularApp.service('SignatureService', SignatureService);

Several other services are added to the app in exactly the same way, and they all seem to work OK. I then have a controller declared and defined as follows:

MyAngularApp.controller('MyController', MyController);
...
var MyController = function ($scope, Service1, Service2, $location, $modal, SignatureService) {
...
}
MyController.$inject = ['$scope', 'Service1', 'Service2', '$location', '$modal', 'SignatureService'];

I am simply using the slightly unconvcentionaly manner of defining the servivce and injecting it that is standard in the app I am working on, as this works for all existing services, and I would prefer to simply slot mine in as per standard.

When the controller loads, I get an [$injector:unpr] in the browser console, with the error info:

$injector/unpr?p0=$scopeProvider <- $scope <- SignatureService

You can't inject $scope into your custom service. It just doesn't make sense since SignatureService can be injected anywhere including other services and other controlles. What $scope is supposed to be if you say inject it into two nested controllers, which one should be injected?

Scope object ( $scope ) is always associated with some DOM node, it is attached to it. That's why you see $scope in controllers and directives. And this is the reason why you can't have it in service: services are not related to specific DOM elements. Of course you can inject $rootScope but this is unlikely what you need in your question.

Summary: $scope is created from the $rootScope and injected in necessary controllers, but you can't injected it into custom service.

UPD. Based on comments you want to use service to define reusable controller methods. In this case I would go with what I call mixin approach. Define methods in the service and mix them in the necessary controllers.

app.service('controllerMixin', function() {
    this.getName = function() {
        alert(this.name);
    };
});

and then extend controller scope with angular.extend :

app.controller('OneController', function($scope, controllerMixin) {
    angular.extend($scope, controllerMixin);
    // define controller specific methods
});

app.controller('TwoController', function($scope, controllerMixin) {
    angular.extend($scope, controllerMixin);
    // define controller specific methods
});

This is pretty effective, because controllerMixin doesn't have any notion of $scope whatsoever, when mixed into controller you refer to the scope with this . Also service doesn't change if you prefer to use controllerAs syntax, you would just extend this :

angular.extend(this, controllerMixin);

Demo: http://plnkr.co/edit/ePhSF8UttR4IgeUjLRSt?p=info

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM