Provider, Value, Constant, Service, Factory, Decorator的區別
首先,provider
, value
, constant
, service
, factory
他們都是provider!
provider是幹啥的?
provider可以爲應用提供通用的服務,形式可以是常量,也可以是對象。
比如我們在controller裏常用的$http
就是AngularJS框架提供的provider~
myApp.controller(‘MainController', function($scope, $http) { $http.get(…) }
provider
那我們自己想定製一個provider,怎麼寫呢~
//定義: $provide.provider('age', { start: 10, $get: function() { return this.start + 2; } }); //或 $provide.provider('age', function($filterProvider){ this.start = 10; this.$get = function() { return this.start + 2; }; }); //調用: app.controller('MainCtrl', function($scope, age) { $scope.age = age; //12 });
provider的基本原則就是通過實現$get
方法來在應用中注入單例,使用的時候拿到的age
就是$get
執行後的結果。 上面例子中的兩種定義方法都可以~
factory
大哥provider
每次出場太繁瑣了,如果我就想定義個$get
,沒別的亂七八糟的呢?這時候該二哥factory
出場了~
$provide.provider('myDate', { $get: function() { return new Date(); } }); //可以寫成 $provide.factory('myDate', function(){ return new Date(); }); //調用: app.controller('MainCtrl', function($scope, myDate) { $scope.myDate = myDate; //current date });
直接第二個參數就是$get要對應的函數實現,代碼簡單了很多有沒有?!
service
這時候我又來勁兒了,我不僅就想定義個$get
,裏面我還就返回個new出來的已有js類,三哥service
閃亮登場~
$provide.provider('myDate', { $get: function() { return new Date(); } }); //可以寫成 $provide.factory('myDate', function(){ return new Date(); }); //可以寫成 $provide.service('myDate', Date);
value vs. constant
更直接的需求來了,我只想定義個$get
,而且就返回個常量~
這時候value
和constant
都可以做到~
$provide.value('pageCount', 7); $provide.constant('pageCount', 7);
兄弟倆功能一樣?雙胞胎?那怎麼可能~
介紹區別前,先得把之前坐小板凳等着的decorator
叫出來~終於該出場了~
區別一:value
可以被修改,constant
一旦聲明無法被修改
$provide.decorator('pageCount', function($delegate) { return $delegate + 1; });
decorator
可以用來修改(修飾)已定義的provider們,除了constant
~
區別二:value
不可在config
裏注入,constant
可以
myApp.config(function(pageCount){ //可以得到constant定義的'pageCount' });
通過底層實現代碼看關係~
function provider(name, provider_) { if (isFunction(provider_)) { provider_ = providerInjector.instantiate(provider_); } if (!provider_.$get) { throw Error('Provider ' + name + ' must define $get factory method.'); } return providerCache[name + providerSuffix] = provider_; } function factory(name, factoryFn) { return provider(name, { $get: factoryFn }); } function service(name, constructor) { return factory(name, ['$injector', function($injector) { return $injector.instantiate(constructor); }]); } function value(name, value) { return factory(name, valueFn(value)); } function constant(name, value) { providerCache[name] = value; instanceCache[name] = value; } function decorator(serviceName, decorFn) { var origProvider = providerInjector.get(serviceName + providerSuffix), orig$get = origProvider.$get; origProvider.$get = function() { var origInstance = instanceInjector.invoke(orig$get, origProvider); return instanceInjector.invoke(decorFn, null, {$delegate: origInstance}); }; }
最後再總結一下provider哥兒幾個的優點~
1. 爲應用提供通用的服務,形式可以是常量或對象
2. 便於模塊化
3. 便於單元測試
轉發鏈接:http://hellobug.github.io/blog/angularjs-providers/