AngularJS中的服务、提供商和工厂之间有什么区别?


当前回答

工厂:您实际在工厂内部创建对象并将其返回的工厂。service:您只有一个使用this关键字定义函数的标准函数的服务。provider:您定义了一个$get,它可以用来获取返回数据的对象。

其他回答

从AngularJS邮件列表中,我得到了一个令人惊叹的线程,它解释了服务与工厂与供应商以及它们的注入用法。编写答案:

服务

语法:module.service('serviceName',function);结果:当将serviceName声明为可注入参数时,将为您提供函数的实例。换句话说,新的FunctionYouPassedToService()。

工厂

语法:module.factory('factoryName',function);结果:当将factoryName声明为可注入参数时,将提供通过调用传递给module.factory的函数引用返回的值。

提供商

语法:module.provider('providerName',function);结果:当将providerName声明为可注入参数时,将提供(newProviderFunction())$get()。在调用$get方法之前实例化构造函数函数-ProviderFunction是传递给module.provider的函数引用。

提供程序的优点是可以在模块配置阶段进行配置。

请参阅此处获取提供的代码。

下面是Misko的进一步解释:

provide.value('a', 123);

function Controller(a) {
  expect(a).toEqual(123);
}

在这种情况下,注入器只是按原样返回值。但是如果您想计算该值呢?然后使用工厂

provide.factory('b', function(a) {
  return a*2;
});

function Controller(b) {
  expect(b).toEqual(246);
}

因此,工厂是一个负责创造价值的职能部门。注意,工厂函数可以要求其他依赖项。

但是,如果你想成为更多的OO,并拥有一个名为Greeter的类呢?

function Greeter(a) {
  this.greet = function() {
    return 'Hello ' + a;
  }
}

然后,要实例化,必须编写

provide.factory('greeter', function(a) {
  return new Greeter(a);
});

然后我们可以像这样在控制器中请求“问候者”

function Controller(greeter) {
  expect(greeter instanceof Greeter).toBe(true);
  expect(greeter.greet()).toEqual('Hello 123');
}

但这太啰嗦了。一个简短的写法是provider.service(“greeter”,greeter);

但是如果我们想在注入之前配置Greeter类呢?然后我们可以写

provide.provider('greeter2', function() {
  var salutation = 'Hello';
  this.setSalutation = function(s) {
    salutation = s;
  }

  function Greeter(a) {
    this.greet = function() {
      return salutation + ' ' + a;
    }
  }

  this.$get = function(a) {
    return new Greeter(a);
  };
});

然后我们可以这样做:

angular.module('abc', []).config(function(greeter2Provider) {
  greeter2Provider.setSalutation('Halo');
});

function Controller(greeter2) {
  expect(greeter2.greet()).toEqual('Halo 123');
}

顺便说一句,服务、工厂和价值都来自提供者。

provider.service = function(name, Class) {
  provider.provide(name, function() {
    this.$get = function($injector) {
      return $injector.instantiate(Class);
    };
  });
}

provider.factory = function(name, factory) {
  provider.provide(name, function() {
    this.$get = function($injector) {
      return $injector.invoke(factory);
    };
  });
}

provider.value = function(name, value) {
  provider.factory(name, function() {
    return value;
  });
};

我的理解很简单。

工厂:您只需在工厂内部创建一个对象并返回它。

服务:

您只需要一个使用此关键字定义函数的标准函数。

供应商:

您定义了一个$get对象,它可以用于获取返回数据的对象。

句法糖是区别。只需要提供程序。或者换句话说,只有提供者才是真正的角度,所有其他提供者都是派生的(以减少代码)。还有一个简单的版本,叫做Value(),它只返回值,不返回计算或函数。偶数值是从提供程序派生的!

那么,为什么会出现这样的并发症,为什么我们不能只使用提供者而忘记其他一切呢?它应该可以帮助我们轻松编写代码,更好地进行沟通。开玩笑的回答是,它越复杂,框架的销售就越好。


可以返回value=value的提供程序一个可以实例化并返回=工厂(+值)提供程序可以实例化+做某事=服务(+工厂,+值)提供者=必须包含名为$get(+Factory,+Service,+Value)的属性

角注入为我们得出这一结论提供了第一个线索。

$injector用于检索提供者“不是服务,不是工厂,而是提供者”定义的对象实例。

更好的答案是:Angular服务由服务工厂创建。这些服务工厂是由服务提供程序创建的函数。服务提供程序是构造函数。实例化时,它们必须包含名为$get的属性,该属性保存服务工厂函数

因此,主供应器和注入器都将就位:)。当$get可以通过从IServiceProvider继承而在提供程序中实现时,Typescript就变得有趣了。

对我来说,理解差异的最佳和最简单的方法是:

var service, factory;
service = factory = function(injection) {}

AngularJS如何实例化特定组件(简化):

// service
var angularService = new service(injection);

// factory
var angularFactory = factory(injection);

因此,对于服务,AngularJS组件是由服务声明函数表示的类的对象实例。对于工厂,它是从工厂声明函数返回的结果。工厂的行为可能与服务相同:

var factoryAsService = function(injection) {
  return new function(injection) {
    // Service content
  }
}

最简单的思考方式如下:

服务是一个单例对象实例。如果您想为代码提供单例对象,请使用服务。工厂是一个阶级。如果您想为代码提供自定义类,请使用工厂(无法使用服务完成,因为它们已经实例化)。

工厂“类”示例在周围的注释中提供,以及提供程序差异。

正如这里的几个人正确指出的,工厂、供应商、服务,甚至价值和常量都是同一事物的版本。您可以将更通用的提供程序分解为所有这些提供程序。像这样:

这是本文的图片来源:

http://www.simplygoodcode.com/2015/11/the-difference-between-service-provider-and-factory-in-angularjs/