為了搞懂service, factory和provider這3種service, 找了一些網站,但還是沒有一個網站真的有講的很淺顯易懂.
交叉參考了一些資料,整理如下:
1. factory
先來看它在angular的原型
function factory(name, factoryFn) {
return provider(name, { $get: factoryFn });
}
第1個參數是name, 作為factory的名稱.
第2個參數是getFn. 取得factory中的物件,array或是字串.
舉例來說:
hippo.factory('awesome', function() {
return 'awesome data';
})
返回一個物件
hippo.factory('awesome', function() {
return {variable: "hello"}
})
也就是說, 使用factory就是去取得其返回的內容來操作.
重點是mg-book中所提到的:
The getFn will be invoked once for the duration of the app lifecycle
也就是說在app的整個生命週期,只會去取一次factory所返回的物件內容。這樣的設計就比較沒有彈性。
2. service
先來看它在angular的原型
function service(name, constructor) {
return factory(name, ['$injector', function($injector) {
return $injector.instantiate(constructor);
}]);
}
第1個參數是name, 作為service的名稱.
第2個參數是constructor), 也就是會用new實體化一個物件.
所以實體是在外部就建立好,在傳入server()後,會用new去宣告這個實體來使用。
因此這樣的設計就比較有彈性,因為可以透過prototype來新增method.
ex: Person.prototype.put = function() {/*…*/}
舉例來說:
var Person = function($http) {
this.getName = function() {
return $http({
method: 'GET',
url: '/api/user'
});
};
};
angular.service('personService', Person);
app.controller('myCtrl', function($scope, personService) {
$scope.name = myService.name;
});
當然也可以不傳入一個物件,自行建立一個匿名實體
app.service('myService', function() {
this.name = "Tony";
});
最後再看一個例子
<div ng-controller="myCtrl">
{{cnt}}
<button ng-click="inc(1)">Inc</button>
{{foo.cnt}}
</div>
<div ng-controller="hisCtrl">
<button ng-click="inc(5)">Inc</button>
</div>
--------------------------------------------
var app = angular.module('myApp',[]);
app.factory('myFactory', function() {
return {
cnt: 1,
inc: function(step) {
this.cnt += step;
}
};
});
app.controller('myCtrl', function($scope,myFactory) {
$scope.name = myFactory.name;
$scope.foo = myFactory;
$scope.cnt = $scope.foo.cnt;
$scope.inc = function() {
$scope.foo.inc(1);
};
});
app.controller('hisCtrl', function($scope,myFactory) {
$scope.inc = function() {
myFactory.inc(5);
};
});
在執行myCtrl的inc()時,myFactory中的cnt會被+1, 而View中顯示foo.cnt也會跟著更新.
在執行hisCtrl的inc()時,myFactory中的cnt會被+5, 而View中顯示foo.cnt也會跟著更新.
但即使$scope.cnt = $scope.foo.cnt, 在更新了myFactory中的cnt後,myCtrl中的$scope.cnt也不會被更新.
綜合以上,factory與service的使用方式很接近. 要判定在何時使用,其實很難分辦.
我自己的看法是,如果已有建立好的物件,用service。若沒有先建好物件,則用factory.
另外, 可以對已建立的service重新傳入新的物件,這樣功能就改變了,但factory則不行。
---
ervice vs provider vs factory? 講了很多,但還是看不太懂.... (http://stackoverflow.com/questions/15666048/service-vs-provider-vs-factory/15666049#15666049)
AngularJS: Factory vs Service vs Provider? 講了很多,但還是看不太懂.... (http://tylermcginnis.com/angularjs-factory-vs-service-vs-provider/)
Understanding Service Types: (http://angular-tips.com/blog/2013/08/understanding-service-types/)
Angular service or factory? (http://iffycan.blogspot.tw/2013/05/angular-service-or-factory.html)
沒有留言:
張貼留言