剛開始學習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的數組和它們被注入的順序決定各個服務被注入到哪裏。