刚开始学习Angular的时候,常常被误解和被初学者问到的组件是 service(), factory(), 和 provide()这几个方法之间的差异。This is where we'll start the twenty-five days of Angular calendar.java
在Angular里面,services做为单例对象在须要到的时候被建立,只有在应用生命周期结束的时候(关闭浏览器)才会被清除。而controllers在不须要的时候就会被销毁了。angularjs
这 就是为何使用controllers在应用里面传递数据不可靠的缘由,特别是使用routing的时候。Services are designed to be the glue between controllers, the minions of data, the slaves of functionality, the worker-bees of our application(就是说services在应用的controllers、 方法、数据以前起到了很关键的做用)web
如今咱们开始看怎么建立service。每一个方法咱们都会看到下面两个同样的参数:后端
name-咱们要定义的service的名字api
function-service方法数组
他们都建立了相同的底层对象类型。实例化后,他们都建立了一个service,这些对象没有什么功能上的差异。浏览器
Angular里面建立service最简单的方式是使用factory()方法。app
factory()让咱们经过返回一个包含service方法和数据的对象来定义一个service。在service方法里面咱们能够注入services,好比 $http 和 $q等。框架
angular.module('myApp.services') .factory('User', function($http) { // injectables go here var backendUrl = "http://localhost:3000"; var service = { // our factory definition user: {}, setName: function(newName) { service.user['name'] = newName; }, setEmail: function(newEmail) { service.user['email'] = newEmail; }, save: function() { return $http.post(backendUrl + '/users', { user: service.user }); } }; return service; });
在应用里面使用factory()方法ide
在应用里面能够很容易地使用factory ,须要到的时候简单地注入就能够了
angular.module('myApp') .controller('MainCtrl', function($scope, User) { $scope.saveUser = User.save; });
何时使用factory()方法
在service里面当咱们仅仅须要的是一个方法和数据的集合且不须要处理复杂的逻辑的时候,factory()是一个很是不错的选择。
注意:须要使用.config()来配置service的时候不能使用factory()方法
service()经过构造函数的方式让咱们建立service,咱们可使用原型模式替代javaScript原始的对象来定义service。
和factory()方法同样咱们也能够在函数的定义里面看到服务的注入
angular.module('myApp.services') .service('User', function($http) { // injectables go here var self = this; // Save reference this.user = {}; this.backendUrl = "http://localhost:3000"; this.setName = function(newName) { self.user['name'] = newName; } this.setEmail = function(newEmail) { self.user['email'] = newEmail; } this.save = function() { return $http.post(self.backendUrl + '/users', { user: self.user }) } });
这里的功能和使用factory()方法的方式同样,service()方法会持有构造函数建立的对象。
在应用里面使用service()方法
angular.module('myApp') .controller('MainCtrl', function($scope, User) { $scope.saveUser = User.save; });
何时适合使用service()方法
service()方法很适合使用在功能控制比较多的service里面
注意:须要使用.config()来配置service的时候不能使用service()方法
provider()是建立service最底层的方式,这也是惟一一个可使用.config()方法配置建立service的方法
不像上面提到的方法那样,咱们在定义的this.$get()方法里面进行依赖注入
angular.module('myApp.services') .provider('User', function() { this.backendUrl = "http://localhost:3000"; this.setBackendUrl = function(newUrl) { if (url) this.backendUrl = newUrl; } this.$get = function($http) { // injectables go here var self = this; var service = { user: {}, setName: function(newName) { service.user['name'] = newName; }, setEmail: function(newEmail) { service.user['email'] = newEmail; }, save: function() { return $http.post(self.backendUrl + '/users', { user: service.user }) } }; return service; } });
在应用里面使用provider()方法
为了给service进行配置,咱们能够将provider注入到.config()方法里面
angular.module('myApp') .config(function(UserProvider) { UserProvider.setBackendUrl("http://myApiBackend.com/api"); })
这样咱们就能够和其余方式同样在应用里面使用这个service了
angular.module('myApp') .controller('MainCtrl', function($scope, User) { $scope.saveUser = User.save; });
何时使用provider()方法
当咱们但愿在应用开始前对service进行配置的时候就须要使用到provider()。好比,咱们须要配置services在不一样的部署环境里面(开发,演示,生产)使用不一样的后端处理的时候就可使用到了
当咱们打算发布开源provider()也是首选建立service的方法,这样就可使用配置的方式来配置services而不是将配置数据硬编码写到代码里面。
Angular 服务是为web应用执行特定任务的单例对象或方法。 注:若是组件是为了内容呈现的功能复用,那么服务就是为组件进行功能复用。
Angular有一些内建的服务(例如:$http),也能够建立本身的服务。内建的服务一般使用“$”开头(与jQuery相似)。
在使用Angular服务的时候,只要将其注册成为Angular组件的一个依赖项目就能够了。Angular会自动对这个服务进行实例化、信赖处理等。
Angular使用“constructor”(构造器)进行信赖注入。信赖将会传递给组件的工厂或构造器方法。由于JavaScript是一个动态类型的语言,Angular的信赖注入子系统不能使用静态的类型来识别服务的信赖。所以,一个组件必须明确的经过使用一种“注释”注入方法来定义它的信赖。例如,使用$inject属性:
var MyController = function($location) { ... }; MyController.$inject = ['$location']; myModule.controller('MyController', MyController);
或者提供一个内联的注入“注释”:
var myService = function($http) { ... }; myModule.factory('myService', ['$http', myService]);
参考:
应用开发人员经过在Angular模块中注册“名字”与“服务工厂”来定义本身的服务。
服务的工厂方法的目的是用来生成单例对象(或者方法function)。生成的对象或者方法能够经过指定到这个服务的信赖来被注入到任意的组件当中。
Angular工厂方法使用消极执行策略,这意味着,只有当须要处理一个依赖的时候,才会为每个服务执行一次。全部的事项都是依赖于这个服务来获取一个被服务工厂方法生成的实例。
Angular容许服务声明其余的服务做为信赖须要,用来构造它们的实例。
为了声明依赖,你能够在工厂方法的参数中指定它们,而后经过使用$inject属性、字符串数组或数组注释以注入注释标明这个方法。
使用数组注释:
function myModuleCfgFn($provide) { $provide.factory('myService', ['dep1', 'dep2', function(dep1, dep2) {}]); }
使用$inject属性:
下面是两个服务的例子,其中一个依赖另外一个,而且这两个服务都依赖Angular框架提供的其余服务:
注意:
batchLog服务依赖于内建的$timeout和$log服务,而且容许消息输出到console.log日志文件中。
routeTemplateMonitor服务依赖于内建的$route服务就像咱们自定义的batchLog服务。
咱们的两个服务都使用工厂方法来标识和数组注释来注入注释以声明它们的依赖。这里要注意的是,在数组中字符串的顺序要与在工厂方法的参数列表中的一致。除非依赖是从方法的参数列表中推断出来的,这个带有ID的数组和它们被注入的顺序决定各个服务被注入到哪里。