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