5

这是我在挖掘 AngularJS 代码时无法弄清楚的,也许你可以帮助解开这个谜团。

为了展示它,我向 AngularJS 种子项目添加了一项服务:

function MyServiceProvider() {
    console.log('its my service');
    this.providerMethod = providerMethod;

    function providerMethod() {
        console.log('its my service.providerMethod');
    }

    this.$get = $get;

    function $get() {
        var innerInjectable = {
             name: 'stam'
        };
        return innerInjectable;
    }
}

var serviceModule = angular.module('myApp.services', []).
    value('version', '0.1').
    provider('myservice',MyServiceProvider);

您可以看到此提供程序公开了 $get 和某个 'providerMethod'。

现在,对于注入用法:如果我们调用 config,我们可以注入整个类并访问“外部”提供程序方法:

serviceModule.config(function(myserviceProvider) {
    console.log('myServiceProvider:',myserviceProvider);
    myserviceProvider.providerMethod();
});

但是当我们将它注入控制器时(注意 Provider-less 名称),只有 $get 返回值被暴露:

function MyCtrl1(myservice) {
    console.log('MyCtrl1.myservice =',myservice,myservice.name);
}
MyCtrl1.$inject = ['myservice'];

控制台输出如下:它的我的服务 myServiceProvider: Constructor {providerMethod: function, $get: function} 它的我的 service.providerMethod MyCtrl1.myservice = Object {name: "stam"} stam

任何人都可以解释其中的区别吗?原因?非常感谢您的任何想法

里奥

PS:我在 angular-ui new ui-router 中看到了这种技术(优秀的项目!)。我需要访问外部提供程序类才能在茉莉花和其他地方进行注入 - 无济于事

4

2 回答 2

9

提供者负责创建实例。在您的示例中,您明确创建了一个提供程序,但事实是每个服务都有一个提供程序,即使它是为它自动创建的。[module].service()并且[module].factory()只是[module].provider().

[module].config()在提供程序注册和配置期间运行,因此您可以更改访问提供程序并使用它们进行操作。这是一个配置事物的地方,因此得名。

从文档(http://docs.angularjs.org/guide/module):

配置块 - 在提供者注册和配置阶段执行。只有提供者和常量可以注入到配置块中。这是为了防止在完全配置之前意外实例化服务。

另一方面,控制器是在配置服务之后实例化的,因此您不应该再与提供者混为一谈。一切都已经配置好了。您现在就可以购买他们的产品了。在这个阶段,注入器不能再注入提供者,只能注入它们创建的实例(服务)。

如果您注册服务myService...

myModule.service('myService', function() {
    // this is your service constructor
});

然后你可以myServiceProvider在配置函数中访问它的提供者...

myModule.config(function(myServiceProvider) {
    // to stuff with your provider here
});

但是当控制器被实例化时,你应该请求服务,而不是他们的提供者,所以这不起作用......

myModule.controller(function(myServiceProvider) {
    ...
});

而这会很好......

myModule.controller(function(myService) {
    ...
});

如果您发现自己需要在控制器中进行配置,您应该停下来重新考虑职责所在。

于 2013-07-04T14:57:36.933 回答
4

从 Angular 邮件列表中,我得到了一个很棒的帖子,它解释了服务、工厂、提供者以及它们的注入用法。我决定在这里把它放在自己的问题中

具体答案是:它是设计使然,允许在配置时配置提供程序。

于 2013-03-27T18:01:18.353 回答