在Angular中,控制器应该是简洁精炼的;一些逻辑和重复性的数据都应该要存储到服务中。控制器就应该在需要他们的时候实例化,在不需要的时候就取消掉。因此,Angular在你每次切换路由的时候,就会清理当前的控制器。但是呢,服务为我们提供了一种长期存储应用数据的方式,同时,也可以在不同的控制器之间统一的使用服务。
Angular为我们提供了三种创建服务的方式:
- Factory
- Service
- Provider
废话不多说,简要分析一下。
factory新创建了一个对象,然后在这个对象上新添属性,最后返回这个对象。
service使用new关键词进行了实例化。只需要在this上添加属性和方法,服务就会自动的返回this。
factory与service在controller的用法并没有什么不同,不要以为service每次注入controller都要new一次,AngularJS 在初始化的时候,会new一次service,所以当 controller 要求注入 service 的时候,AngularJS 就会把已经 new 过的的 service 給 controller。
注意:Provider 都是 singleton !!!!!
沒错,所以就算 service 有 new 这个指令,可是其实也只是做一次而已。
每个要求注入 service 的 components 拿到的都会是同一个service reference。
factory 也是相同的情況,全部系统共用一个 Factory reference。
所以我们才用Provider做controller之间传值的桥梁!!!
Provider:
provider是唯一一种可以创建用来注入到config()函数的服务的方式。想在你的服务启动之前,进行一些模块化的配置的话,就使用provider。
来简单的说明一下 Provider 跟 Factory 和 Service 的关系。个人觉得 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函数访问
this._artist = '';
this.thingFromConfig = '';
// 只有$get函数返回的属性才能被控制器访问
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有三个部分,第一部分是私有变量和私有函数,这些变量和函数会在以后被修改。第二部分是在app.config函数里可以访问的变量和函数,所以,他们可以在在其他地方使用之前被修改。注意,这些变量和函数一定要添加到this上面才行。在我们的例子中,app.config()函数能够修改的只有thingFromConfig。第三部分是在控制器里可以访问的变量和函数。
当使用 provider创建服务的时候,唯一可以让控制器访问的属性和方法是在$get()函数里返回的属性和方法。将$get添加到了this上面,最终这个函数会被返回。
网友评论