协慌网

登录 贡献 社区

angular.service vs angular.factory

我已经看到angular.factory()angular.service()用于声明服务; 但是,我在官方文档中找不到 angular.service

这两种方法有什么区别?应该用什么(假设他们做不同的事情)?

答案

angular.service('myService', myServiceFunction);
  angular.factory('myFactory', myFactoryFunction);

我无法绕过这个概念,直到我这样说:

服务 :你编写的函数将是新的

myInjectedService  <----  new myServiceFunction()

Factory :将调用您编写的函数 (构造函数):

myInjectedFactory  <---  myFactoryFunction()

你用它做什么取决于你,但有一些有用的模式......

比如编写一个服务函数来公开一个公共 API:

function myServiceFunction() {
  this.awesomeApi = function(optional) {
    // calculate some stuff
    return awesomeListOfValues;
  }
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.awesome = myInjectedService.awesomeApi();

或使用工厂函数公开公共 API:

function myFactoryFunction() {
  var aPrivateVariable = "yay";

  function hello() {
    return "hello mars " + aPrivateVariable;
  }

  // expose a public API
  return {
    hello: hello
  };
}
---------------------------------------------------------------------------------
// Injected in your controller
$scope.hello = myInjectedFactory.hello();

或使用工厂函数返回构造函数:

function myFactoryFunction() {
    return function() {
        var a = 2;
        this.a2 = function() {
            return a*2;
        };
    };
}
---------------------------------------------------------------------------------
// Injected in your controller
var myShinyNewObject = new myInjectedFactory();
$scope.four = myShinyNewObject.a2();

哪一个使用?...

你可以用两者完成同样的事情。但是,在某些情况下, 工厂可以更灵活地创建具有更简单语法的注入。这是因为 myInjectedService 必须始终是一个对象,myInjectedFactory 可以是一个对象,一个函数引用或任何值。例如,如果您编写了一个服务来创建构造函数(如上面的上一个示例所示),则必须实例化它:

var myShinyNewObject = new myInjectedService.myFunction()

这可能比这更不可取:

var myShinyNewObject = new myInjectedFactory();

(但是你应该首先考虑使用这种类型的模式,因为控制器中的对象会创建难以模拟测试的难以跟踪的依赖关系。更好地让服务管理对象的集合你比使用new()狡猾的。)


还有一件事,他们都是单身人士......

还要记住,在这两种情况下,angular 都可以帮助您管理单身人士。无论您注入服务或功能的位置或次数,您都将获得对同一对象或功能的相同引用。 (除了工厂只返回一个数字或字符串之类的值。在这种情况下,您将始终获得相同的值,但不是引用。)

简单的说 ..

// Service
service = (a, b) => {
  a.lastName = b;
  return a;
};

// Factory
factory = (a, b) => Object.assign({}, a, { lastName: b });

const fullName = { firstName: 'john' };

// Service
const lastNameService = (a, b) => {
  a.lastName = b;
  return a;
};
console.log(lastNameService(fullName, 'doe'));

// Factory
const lastNameFactory = (a, b) => 
  Object.assign({}, a, { lastName: b })
console.log(lastNameFactory(fullName, 'doe'));

以下是主要差异:

服务

语法: module.service( 'serviceName', function );

结果:将 serviceName 声明为 injectable 参数时,将向您提供传递给module.service 的函数实例

用法:通过简单地向注入的函数引用附加( )共享对调用有用的实用程序函数非常有用。也可以使用injectedArg.call( this )或类似的方式运行。

工厂

语法: module.factory( 'factoryName', function );

结果:当将 factoryName 声明为 injectable 参数时,将通过调用传递给module.factory 的函数引用来提供返回

用法:用于返回一个'class'函数,然后可以用来创建实例。

这是使用服务和工厂的示例 。阅读更多关于AngularJS Service vs Factory 的信息

您还可以检查AngularJS 文档以及有关服务与工厂混淆的 stackoverflow 上的类似问题。