何时使用工厂以及何时使用服务 - 计数器方法在书中提出

时间:2015-03-26 11:02:25

标签: javascript angularjs

我正在阅读有关角度服务的this book。在总结何时使用提供程序的servicefactory方法时,作者会说明以下内容:

  

如果将服务定义为类并且需要调用定义的构造函数,则应使用服务方法。使用   如果将服务定义为对象实例,则为工厂方法   并且不需要调用构造函数。

我想知道这是否是一个错字或我一直在滥用它们。在我需要实例时,我总是使用factory方法来获取构造函数和service

修改

例如,我有一个验证器服务,应用程序中的每个控制器都应该拥有自己的实例。我把它定义为一个类:

function ValidatorService() {
    this.addErrorRule = function (event, rule) {};
    this.validate = function (values) {}
}

现在,我将使用factory方法在角度系统中定义它,如下所示:

angular.module("validation").factory('ValidatorService', function () {
    return ValidatorService;
});

每当控制器需要ValidatorService时,它将提供构造函数,可以从中实例化服务。

但根据引用:

  

如果您将服务定义为a,则应使用服务方法   class,需要调用定义的构造函数。

我应该这样做:

angular.module("validation").service('ValidatorService', ValidatorService);

但在这种情况下,angular将实例化一个将在所有控制器之间共享的服务实例。

3 个答案:

答案 0 :(得分:1)

接受 从AngularJS邮件列表中,我得到了一个惊人的线程,解释了服务与工厂与提供商及其注入使用情况。编译答案:

<强>服务

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

<强>工厂

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

<强>提供商

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

提供商的优势在于可以在模块配置阶段配置它们。

答案 1 :(得分:1)

在Angular service配方中,传递的函数就像构造函数一样被调用,这就是作者在他说

时所指的内容。
  

如果您将服务定义为a,则应使用服务方法   class,需要调用定义的构造函数。

对于factory,框架执行配方函数,并且每次注入服务时都会缓存并返回返回值。

通常工厂用于返回对象,但对于factory配方实现,返回值是构造函数,因此您的解释与作者解释的不同。

答案 2 :(得分:1)

我会采取不同的方法来回答你的问题。我相信代码可以改进以适应service并实现您引用的建议:

  

如果将服务定义为类并且需要调用定义的构造函数,则应使用服务方法。

不是创建需要将规则添加到实例的ValidatorService实例来运行验证,而应该尝试更实用的方法。

&#13;
&#13;
function ValidatorService() {
  this.validate = function(rules, values) {
    //Loop over rules/values
    return Math.random() * 10 //used only to show that validates are independent;
  };
}

angular
  .module('test', [])
  .service('validator', ValidatorService)
  .factory('validatorFac', function () {
    return function (rules, values) {
        return Math.random() * 10; //used only to show that validates are independent;
    };
  })
  .controller('TestController', ['$scope', 'validator', function($scope, validator) {
    $scope.isValid = validator.validate([],[])
  }])
  .controller('AnotherTestController', ['$scope', 'validator', function($scope, validator) {
    $scope.isValid = validator.validate([],[])
  }])
  .controller('TestFacController', ['$scope', 'validatorFac', function($scope, validatorFac) {
    $scope.isValid = validatorFac([],[])
  }])
  .controller('AnotherTestFacController', ['$scope', 'validatorFac', function($scope, validatorFac) {
    $scope.isValid = validatorFac([],[])
  }]);
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test">
  <div ng-controller="TestController">
    <p>Is Valid: {{ isValid }}</p>
  </div>
  <div ng-controller="AnotherTestController">
    <p>Is Valid: {{ isValid }}</p>
  </div>
  <div ng-controller="TestFacController">
    <p>Is Valid: {{ isValid }}</p>
  </div>
  <div ng-controller="AnotherTestFacController">
    <p>Is Valid: {{ isValid }}</p>
  </div>
</div>
&#13;
&#13;
&#13;

正如您所看到的,服务和工厂方法基本相同。我提倡适用于servicefactory的这种功能方法的好处是你应该通过实例化更少的对象来减少垃圾收集,它应该是从未实例化的更快的实现,并且没有国家保持。

最后,为了回答您的问题,您并没有滥用servicefactory。相反,您引用的文档似乎希望您不直接在服务中维护状态,因为它是一个单例。我的建议是改变您的代码,使其更像这样,因为您可能适合&#34;角度方式&#34;更好。