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


当前回答

另外一个澄清是,工厂可以创建函数/原语,而服务不能。看看这个基于Epokk的jsFiddle:http://jsfiddle.net/skeller88/PxdSP/1351/.

工厂返回一个可以调用的函数:

myApp.factory('helloWorldFromFactory', function() {
  return function() {
    return "Hello, World!";
  };
});

工厂还可以返回具有可调用方法的对象:

myApp.factory('helloWorldFromFactory', function() {
  return {
    sayHello: function() {
      return "Hello, World!";
    }
  };
});

该服务返回一个具有可调用方法的对象:

myApp.service('helloWorldFromService', function() {
  this.sayHello = function() {
     return "Hello, World!";
  };
});

有关详细信息,请参阅我写的关于差异的帖子:http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/

其他回答

派对有点晚了。但我认为这对那些想学习(或清楚)如何使用工厂、服务和提供者方法开发Angular JS自定义服务的人更有用。

我看到了这段视频,它清楚地解释了开发AngularJS定制服务的工厂、服务和供应商方法:

https://www.youtube.com/watch?v=oUXku28ex-米

源代码:http://www.techcbt.com/Post/353/Angular-JS-basics/how-to-develop-angularjs-custom-service

此处发布的代码直接从上述来源复制,以使读者受益。

基于“工厂”的定制服务的代码如下(它与同步和异步版本一起调用http服务):

var app=角度模块(“app”,[]);app.controller('imp',['$scope','calcFactory',函数($scope,calcFactory){$scope.a=10;$scope.b=20;$scope.doSum=函数(){//$scope.sum=calcFactory.getSum($scope.a,$scope.b)//同步的calcFactory.getSum($scope.a,$scope.b,函数(r){//aynchronous$scope.sum=r;});};}]);app.factory('calFactory',['$http','$log',函数($http,$log){$log.log(“实例化calcFactory.”);var oCalcService={};//oCalcService.getSum=函数(a,b){//返回parseInt(a)+parseInt(b);//};//oCalcService.getSum=函数(a,b,cb){//var s=parseInt(a)+parseInt(b);//cb(s);//};oCalcService.getSum=函数(a,b,cb){//使用http服务$http({url:'http://localhost:4467/Sum?a='+a+'和b='+b,方法:'GET'}).然后(函数(resp){$log.log(对应数据);cb(相应数据);},函数(resp){$log.error(“出现错误”);});};return oCalcService;}]);

自定义服务的“服务”方法的代码(这与“工厂”非常相似,但从语法角度来看不同):

var app=角度模块(“app”,[]);app.controller('imp',['$scope','calcService',函数($scope,calcService){$scope.a=10;$scope.b=20;$scope.doSum=函数(){//$scope.sum=calcService.getSum($scope.a,$scope.b);calcService.getSum($scope.a,$scope.b,函数(r){$scope.sum=r;}); };}]);app.service('calService',['$http','$log',函数($http,$log){$log.log(“实例化calcService..”);//this.getSum=函数(a,b){//返回parseInt(a)+parseInt(b);//};//this.getSum=函数(a,b,cb){//var s=parseInt(a)+parseInt(b);//cb(s);//};this.getSum=函数(a,b,cb){$http({url:'http://localhost:4467/Sum?a='+a+'和b='+b,方法:'GET'}).然后(函数(resp){$log.log(对应数据);cb(相应数据);},函数(resp){$log.error(“出现错误”);});};}]);

自定义服务的“提供者”方法的代码(如果您想开发可配置的服务,这是必要的):

var app=角度模块(“app”,[]);app.controller('imp',['$scope','calcService',函数($scope,calcService){$scope.a=10;$scope.b=20;$scope.doSum=函数(){//$scope.sum=calcService.getSum($scope.a,$scope.b);calcService.getSum($scope.a,$scope.b,函数(r){$scope.sum=r;}); };}]);app.provider('calService',函数(){var baseUrl=“”;this.config=函数(url){baseUrl=url;};这一点$get=['$log','$http',函数($log,$http){$log.log(“正在实例化calcService…”)var oCalcService={};//oCalcService.getSum=函数(a,b){//返回parseInt(a)+parseInt(b);//};//oCalcService.getSum=函数(a,b,cb){//var s=parseInt(a)+parseInt(b);//cb(s); //};oCalcService.getSum=函数(a,b,cb){$http({url:baseUrl+'/Sum?a=‘+a+’&b=‘+b,方法:'GET'}).然后(函数(resp){$log.log(对应数据);cb(相应数据);},函数(resp){$log.error(“出现错误”);});}; return oCalcService;}];});app.config(['calServiceProvider',函数(calServiceProvider){calcServiceProvider.config(“http://localhost:4467");}]);

最后是与上述任何服务一起工作的UI:

<html><head><title></title><script src=“https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js“></script><script type=“text/javascript”src=“t03.js”></script></head><body ng app=“app”><div ng controller=“emp”><div>a的值为{{a}},但你可以改变<input-type=text-ng-model=“a”/><br>b的值是{{b}},但你可以改变<input-type=text-ng-model=“b”/><br></div>总和={{Sum}}<br><button ng click=“doSum()”>计算</button></div></body></html>

为了澄清这一点,从AngularJS源代码中,您可以看到一个服务只是调用工厂函数,而工厂函数反过来调用提供程序函数:

function factory(name, factoryFn) { 
    return provider(name, { $get: factoryFn }); 
}

function service(name, constructor) {
    return factory(name, ['$injector', function($injector) {
      return $injector.instantiate(constructor);
    }]);
}

了解AngularJS工厂、服务和提供商

所有这些都用于共享可重用的单例对象。它有助于在应用程序/各种组件/模块之间共享可重用代码。

来自文档服务/工厂:延迟实例化–Angular仅在应用程序组件依赖于服务/工厂时实例化它。单件–每个组件依赖于服务获取对单个实例的引用由服务工厂生成。

工厂

工厂是一个函数,您可以在创建对象之前操作/添加逻辑,然后返回新创建的对象。

app.factory('MyFactory', function() {
    var serviceObj = {};
    //creating an object with methods/functions or variables
    serviceObj.myFunction = function() {
        //TO DO:
    };
    //return that object
    return serviceObj;
});

用法

它可以只是像类一样的函数集合。因此,当您将其注入控制器/工厂/指令函数时,它可以在不同的控制器中实例化。每个应用程序只实例化一次。

服务

在查看服务时,只需考虑阵列原型。服务是一个使用“new”关键字实例化新对象的函数。您可以使用this关键字将财产和函数添加到服务对象。与工厂不同,它不返回任何内容(它返回包含方法/财产的对象)。

app.service('MyService', function() {
    //directly binding events to this context
    this.myServiceFunction = function() {
        //TO DO:
    };
});

用法

当您需要在整个应用程序中共享单个对象时,请使用它。例如,经过验证的用户详细信息、可共享的方法/数据、实用程序功能等。

供应商

提供程序用于创建可配置的服务对象。您可以通过config函数配置服务设置。它使用$get()函数返回一个值。$get函数在运行阶段以角度执行。

app.provider('configurableService', function() {
    var name = '';
    //this method can be be available at configuration time inside app.config.
    this.setName = function(newName) {
        name = newName;
    };
    this.$get = function() {
        var getName = function() {
             return name;
        };
        return {
            getName: getName //exposed object to where it gets injected.
        };
    };
});

用法

当您需要在服务对象可用之前为其提供模块化配置时,例如,假设您希望根据环境(如dev、stage或prod)设置API URL

注释只有提供程序在angular的配置阶段可用,而服务和工厂不是。

希望这能澄清您对工厂、服务和供应商的理解。

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

另外一个澄清是,工厂可以创建函数/原语,而服务不能。看看这个基于Epokk的jsFiddle:http://jsfiddle.net/skeller88/PxdSP/1351/.

工厂返回一个可以调用的函数:

myApp.factory('helloWorldFromFactory', function() {
  return function() {
    return "Hello, World!";
  };
});

工厂还可以返回具有可调用方法的对象:

myApp.factory('helloWorldFromFactory', function() {
  return {
    sayHello: function() {
      return "Hello, World!";
    }
  };
});

该服务返回一个具有可调用方法的对象:

myApp.service('helloWorldFromService', function() {
  this.sayHello = function() {
     return "Hello, World!";
  };
});

有关详细信息,请参阅我写的关于差异的帖子:http://www.shanemkeller.com/tldr-services-vs-factories-in-angular/