服務的用途
- 服務提供了一種能在應用的整個生命周期內保持數據的方法,它能夠在控制器之間進行通信,並且能保證數據的一致性
- 服務提供了把特定功能相關聯的方法集中在一起的接口
如何創建服務
- angularJS提供了一些內置服務,同時為復雜應用創建我們自己的服務也是很有必要的
- anguarjs中創建自己的服務是非常容易的,只需要注冊這個服務即可。服務被注冊后,angularJS編譯器就可以引用他,並且在運行時把它當作依賴加載進來
示例:
angular.module('freefedService',[]).factory('ajaxService',['$http','$q',function($http,$q){ var deferred = $q.defer(); return { ajaxFunc : function(params){ var params = params || {}; $http({ method : params.method || 'post', url : params.url || '', data : params. data || {}, responseType : params.type || 'json' }).success(function(data){ deferred.resolve(data); }).error(function(reason){ deferred.reject(reason); }); return deferred.promise() } }; }]);
如何使用服務
- 可以在控制器、指令或另外一個服務中通過依賴聲明的方式來使用服務
demo.html <!doctype html> <html ng-app="freefedApp"> <head> <title>angular應用demo</title> <script src="angular.js"></script> <script src="service.js"></script> <script src="app.js"></script> </head> <body> <div ng-controller="userCtrl"> <div class="user-center"> <span class="user-icon"><img src="{{vm.user.pic}}" /></span> <span class="user-name">{{vm.user.name}}</span> </div> </div> </body> </html>
service.js angular.module('freefedService',[]).factory('ajaxService',['$http','$q',function($http,$q){ var deferred = $q.defer(); return { ajaxFunc : function(params){ var params = params || {}; $http({ method : params.method || 'post', url : params.url || '', data : params. data || {}, responseType : params.type || 'json' }).success(function(data){ deferred.resolve(data); }).error(function(reason){ deferred.reject(reason); }); return deferred.promise() } }; }]); app.js /*聲明module*/ var module = angular.module('freefedApp',['freefedService']); /*聲明控制器*/ module.controller('userCtrl',['$scope','ajaxService',function($scope,ajaxService){ var vm = $scope.vm = $scope.vm || {}; vm.user = {}; //調用ajaxService服務 ajaxService.ajaxFunc( { url : '/getUser.php' } ).then(function(data){ vm.user.pic= data.pic; vm.user.name = data.name; },function(error){ alert( error.msg ); } ); }])
多種創建服務方式
-
service
使用service可以注冊一個支持構造函數的服務,它允許我們為服務對象注冊一個構造函數,service函數接收兩個參數:
name(字符串)需要注冊的服務名
constructor(函數) 構造函數,調用它來實例化服務對象, 注入到應用中,會生成一個構造函數的實例對象被引用
angular.module('freefedService',[]).service('myService',function(){ this.getUser = function(){}; });
-
factory
factory是創建和配置服務的最快捷的方式,相對於service函數,factory更加適用於當你在設計一個需要私有方法或屬性的類的時候使用,factory函數接收兩個參數:
name(字符串) 需要注冊的服務名
getFn(函數) 這個函數會在angularJS創建服務時調用
//有私有方法、屬性的類示例: angular.module('freefedService',[]).factory('myService',function(){ var _version = '1.1.0'; //私有屬性 var _method = function(){ }; //私有方法 return new function(){ this.getVersion= function(){ return _version; }; this.method = function(){ _method(); //調用私有方法 }; }; }); //普通示例: angular.module('freefedService',[]).factory('myService',function(){ return { getUser : function(){} }; });
-
provider
所有服務工廠都是由provider服務創建的,provide服務負責在運行時初始化這些提供者,provider函數接收兩個參數:
name(字符串) 需要注冊的服務名
aProvider(對象、函數)
- aProvider是函數,那么它會通過依賴注入被調用, 並且通過$get方法返回一個對象
angular.module('freefedService',[]).provider('myService',function(){ this.setUrl = function(){}; this.$get = function( $http ){ //依賴注入在此加入 return { getUser : function(){} }; }; });
- aProvider是對象,要帶有$get方法
angular.module('freefedService',[]).provider('myService',{ setUrl : function(){}; $get: function( $http ){ //依賴注入在此加入 return { getUser : function(){} }; }; });
什么場景使用provider方式創建服務
如果希望在config函數中可以對服務進行配置,必須用provider()來定義服務,示例
demo.html <!doctype html> <html ng-app="freefedApp"> <head> <title>angular應用demo</title> <script src="angular.js"></script> <script src="service.js"></script> <script src="app.js"></script> </head> <body> <div ng-controller="userCtrl"> <div class="user-center"> <span class="user-icon"><img src="{{vm.user.pic}}" /></span> <span class="user-name">{{vm.user.name}}</span> </div> </div> </body> </html>
service.js angular.module('freefedService',[]).provider('userService',function(){ var baseUrl = 'http://dev.freefed.com' this.setUrl = function( base ){ baseUrl = base || baseUrl; }; this.$get = function( $http ){ //依賴注入在此加入 return { getUser : function(){ $http({ url : baseUrl + '/getUser.php' }); } }; }; }); app.js /*聲明module*/ var module = angular.module('freefedApp',['freefedService']). config('userServiceProvider',['userServiceProvider',function(userServiceProvider){ //當我們希望在應用開始前對service進行配置的時候就需要使用到provider() userServiceProvider.baseUrl = 'http:://product.freefed.com'; }]); /*聲明控制器*/ module.controller('userCtrl',['$scope','userService',function($scope,userService){ var vm = $scope.vm = $scope.vm || {}; vm.user = {}; //調用userService服務 userService. getUser(); }]);
-
constant
可以將一個已存在的常量值注冊為服務,通過注入引用到應用中,constant()接收兩個參數:
name(字符串) 需要注冊的常量名
value(值或對象) 需要注冊的常量的值
angular.module('freefedApp',[]).constant('configService',{ //把后台系統所有接口,以及硬編碼的文本等都全部提取到這里來統一配置 UPLOAD_ERROR_TIP : '文件上傳失敗', UPLOAD_SUCCESS_TIP : '文件上傳成功', ...... BASE_URL : 'http://prodoct.freefed.com/', api : { login : '/login.php' user : '/user.php' ....... } });
-
value
如果通過provider的$get返回的是一個常量,那就沒必要定義一個包含復雜功能的完成服務,可以直接通過value函數方便的定義一個服務,value()接收兩個參數:
name(字符串) 需要注冊的常量名
value(值或對象) 將這個值作為可注入的實例返回
angular.module('freefedApp',[]).value('my',{ mytext : 'freefed welcome to you', change : function(){} });
value()與constant()的區別
-
通過constant()聲明的常量可以直接注入到配置函數中,通過value()聲明的則不行,如下:
//constant() angular.module('freefedConfig',[]).constant('apikey','kly78hjqp1k3b'); angular.module('freefedApp',['freefedConfig']).config( ['apikey',funciton( apikey ){ var key = apikey; //可以正常訪問到常量apikey的值 }] ); //value() angular.module('freefedConfig',[]).value('apikey','kly78hjqp1k3b'); angular.module('freefedApp',['freefedConfig']).value( ['apikey',funciton( apikey ){ //將會拋出錯誤, 未知的 provider : apikey ,因為在config函數內部無法訪問這個值 }] );
-
通常用value()來注冊服務對象,用constant()來配置數據
-