一尘不染

angular.service 与 angular.factory

javascript

我见过angular.factory()和angular.service()都用于声明服务;但是,我在官方文档中找不到任何地方。 angular.service

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


阅读 126

收藏
2022-04-22

共1个答案

一尘不染

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

在我这样说之前,我很难理解这个概念:

服务:您编写的功能将是新的

  myInjectedService  <----  new myServiceFunction()

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

  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()狡猾地使用。)


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

还要记住,在这两种情况下,角度都可以帮助您管理单例。无论您在何处或多少次注入您的服务或函数,您都将获得对同一对象或函数的相同引用。(工厂只返回一个数字或字符串之类的值除外。在这种情况下,您将始终获得相同的值,但不是引用。)

2022-04-22