在AngularJS中,系統內置的服務都是以$
開頭,所以我們的自定義服務盡量避免以$
開頭。自定義服務的方式有如下幾種:
- 使用Module的provider方法
- 使用Module的factory方法
- 使用Module的service方法
使用provider方法
app.provider('myProvider', function () { this.$get = function () { //do somthing }; });
通過provider方法創建的服務一定要包含$get
方法,provider注入的結果就是$get
方法返回的結果,如果不包含$get
方法,則程序會報錯。
在三種創建服務的方法中,只有使用provider方法創建的服務才可以傳進config函數,以用於在對象啟用之前,對模塊進行配置。但是在config中進行配置的只能是在$get
函數之外定義的變量,在下面定義的provider中只有artist
與thingFromConfig
兩個變量可以被訪問到,而getArtist
與getThingFromConfig
兩個方法是不能被在config函數中訪問到的。
而且在注入config函數中時,參數名必須由服務名+Provider
組成,例如下面的例子注入到config函數中的就是myProviderProvider
app.controller('myCtrl', ['$scope', 'myProvider', function ($scope, myProvider) { console.log(myProvider.getThingFromConfig()); //kingx name }]); app.provider('myProvider', function () { this.artist = ''; this.thingFromConfig = ''; this.$get = function () { var that = this; return { getArtist: function () { return that.artist; }, getThingFromConfig: function () { return that.thingFromConfig; } } }; }); app.config(function (myProviderProvider) { //注意這里參數的名字 myProviderProvider.thingFromConfig = 'kingx name'; });
使用provider方法
app.factory('myFactory', function ($http) { //不一定是要對象類型,實際為任意類型 var factory = {}; return factory; });
通過factory方法創建的服務必須有返回值,即必須有return函數,它可以返回任意類型的值,包括基本數據類型或者對象類型。如果沒有return函數,則會報錯。
factory注入的結果就是return返回的結果,可以在被注入的對象中使用注入的結果定義的各種方法.
1 app.controller('myCtrl', ['$scope', 'myFactory', function ($scope, myFactory) { 2 console.log(myFactory.getName()); //foo 3 //請求當前文件夾下的test.html 4 myFactory.getData('./test.html').then(function (response) { 5 console.log(response); //返回test.html的字符串形式 6 }); 7 }]); 8 9 /**------------ 使用factory方法 -----------------*/ 10 app.factory('myFactory', function ($http) { 11 var factory = {}; 12 var _name = 'foo'; 13 //模仿ajax請求 14 factory.getData = function (url) { 15 return $http({ 16 method: 'get', 17 url: url 18 }); 19 }; 20 21 factory.getName = function () { 22 return _name; 23 }; 24 25 return factory; //這里返回的是factory 包含2個方法 26 });
使用service方法
通過service方法創建的服務,可以不用返回任何值,因為service方法本身返回一個構造器,系統會用new關鍵字來創建一個對象,所以我們可以在service內部使用this關鍵字,對service進行擴展。
1 app.controller('myCtrl', ['$scope', 'myService', function ($scope, myService) { 2 console.log(myService); 3 myService.setName('foo'); 4 console.log(myService.getName()); 5 }]); 6 7 /**------------ 使用service方法 -----------------*/ 8 app.service('myService', function () { 9 this._name = ''; 10 11 this.getName = function () { 12 return this._name; 13 }; 14 15 this.setName = function (name) { 16 this._name = name; 17 }; 18 19 });
如果使用具有返回值的寫法,返回的值必須是一個對象,如果只返回基本類型,則實際返回的還是相當於this
1 app.service('myService', function () { 2 var obj = {}; 3 this._name = ''; 4 5 obj.getName = function () { 6 return this._name; 7 }; 8 9 obj.setName = function (name) { 10 this._name = name; 11 }; 12 return obj; 13 });
三種方法的比較
- 需要在config中進行全局配置的話,只能選擇provider方法
- factory和service是使用比較頻繁的創建服務的方法。他們之間的唯一區別是:service方法用於注入的結果通常是new出來的對象,factory方法注入的結果通常是一系列的functions
- provider是創建服務最為復雜的方法,除非你需要創建一個可以復用的代碼段並且需要進行全局配置,才需要使用provider創建
-
所有具有特定性目的的對象都是通過factory方法去創建