在Angular中,控制器應(yīng)該是簡潔精煉的;一些邏輯和重復(fù)性的數(shù)據(jù)都應(yīng)該要存儲到服務(wù)中。控制器就應(yīng)該在需要他們的時候?qū)嵗诓恍枰臅r候就取消掉。因此,Angular在你每次切換路由的時候,就會清理當前的控制器。但是呢,服務(wù)為我們提供了一種長期存儲應(yīng)用數(shù)據(jù)的方式,同時,也可以在不同的控制器之間統(tǒng)一的使用服務(wù)。
Angular為我們提供了三種創(chuàng)建服務(wù)的方式:
- Factory
- Service
- Provider
廢話不多說,簡要分析一下。
factory新創(chuàng)建了一個對象,然后在這個對象上新添屬性,最后返回這個對象。
service使用new關(guān)鍵詞進行了實例化。只需要在this上添加屬性和方法,服務(wù)就會自動的返回this。
factory與service在controller的用法并沒有什么不同,不要以為service每次注入controller都要new一次,AngularJS 在初始化的時候,會new一次service,所以當 controller 要求注入 service 的時候,AngularJS 就會把已經(jīng) new 過的的 service 給 controller。
注意:Provider 都是 singleton !!!!!
沒錯,所以就算 service 有 new 這個指令,可是其實也只是做一次而已。
每個要求注入 service 的 components 拿到的都會是同一個service reference。
factory 也是相同的情況,全部系統(tǒng)共用一個 Factory reference。
所以我們才用Provider做controller之間傳值的橋梁!!!
Provider:
provider是唯一一種可以創(chuàng)建用來注入到config()函數(shù)的服務(wù)的方式。想在你的服務(wù)啟動之前,進行一些模塊化的配置的話,就使用provider。
來簡單的說明一下 Provider 跟 Factory 和 Service 的關(guān)系。個人覺得 Mark Meyer 在 top 10 mistakes angularjs developers make 文章解說的很好。把 code 借來并附上我的注解。
// factory 的底層就是回傳 provider 的 $get 裡的值
function factory(name, factoryFn) {
return provider(name, { $get: factoryFn });
}
// service 的底層就是在 factory 裡使用 $jnjector.instantiate 跟 construct 建立新物件
// ( $injector.instantiate 會做 new instance 的動作)
function service(name, constructor) {
return factory(name, ['$injector',
function($injector) {
return $injector.instantiate(constructor);
}]);
}
再來看看provider的使用方式:
app.provider('My', function () {
// 私有屬性和方法
var artist;
// 只有直接添加在this上的屬性才能被config函數(shù)訪問
this._artist = '';
this.thingFromConfig = '';
// 只有$get函數(shù)返回的屬性才能被控制器訪問
this.$get = function () {
var that = this;
return {
getArtist: function () {
return that._artist;
},
thingFromConfig: that.thingFromConfig
};
};
})
.config(['MyProvider', function ( MyProvider ) {
MyProvider.thingFromConfig = 'this is set in config()';
}])
.controller('myProviderCtrl', [
'$scope', 'My',
function ( $scope, My ) {
$scope.artist = My.thingFromConfig;
}]);
你可以認為provider有三個部分,第一部分是私有變量和私有函數(shù),這些變量和函數(shù)會在以后被修改。第二部分是在app.config函數(shù)里可以訪問的變量和函數(shù),所以,他們可以在在其他地方使用之前被修改。注意,這些變量和函數(shù)一定要添加到this上面才行。在我們的例子中,app.config()函數(shù)能夠修改的只有thingFromConfig。第三部分是在控制器里可以訪問的變量和函數(shù)。
當使用 provider創(chuàng)建服務(wù)的時候,唯一可以讓控制器訪問的屬性和方法是在$get()函數(shù)里返回的屬性和方法。將$get添加到了this上面,最終這個函數(shù)會被返回。