module 与provide的区别
module和provide是用来注册服务到injector中的。查看官方的API,可以看到$provide提供了provide()、constant()、value()、factory()、service()来创建各种不同性质的服务;angular.Module中也提供了这5个服务注册方法。其实2者功能是完全一样的,就是用来向DI容器注册服务到injector中。
对于服务 provide 拥有的方法
provider
factory
service
value
constant
decorator
对于具体实现
provider
function provider(name,provider_){
assertNotHasOwnProperty(name,'service');
if(isFunction(provider_) || isAArray(provider_)){
provider_ = providerInjector.instantiate(provider_);
}
if(!provider_.$get){
throw $injectorMinErr('');
}
// 缓存在 providerCache 里面的
return providerCache[name+ providerSuffix]=provider_;
}
factory
function factory(name,factoryFn,enforce){
return provider(name,{
$get: enforce !== false ? enforceReturnValue(name,factoryFn):factoryFn
})
}
service
function service(name,constructor){
//
return factory(name,['$injector',function($injector){
return $injector.instantiate(constructor);
}])
}
value
function value(name,val){
return factory(name,valueFn(val),false);
}
constant
function constant(name,value){
assertNotHasOwnProperty(name,'constant');
providerCache[name] = value;
instanceCache[name] = value;
}
decorator
function decorator(serviceName,decorFn){
var origProvider = providerInjector.get(serviceName+ providerSuffix);
var orig$get = origProvider.$get;
origProvider.$get = function(){
var origInstance = instanceInjector.invoke(orig$get,origProvider);
return instanceInjector.invoke(decorFn,null,{$delegate:origInstance});
}
}
对于decorator(装饰),主要是实现对于model 的service进行重新修改,使用案例
// Code goes here
var Mail = function() {
this.receiver = '';
this.body = '';
this.cc = [];
};
Mail.prototype.setReceiver = function(receiver) {
this.receiver = receiver;
};
Mail.prototype.setBody = function(body) {
this.body = body;
};
angular.module('A', []).service('Mail', Mail);
//
angular.module('B', ['A']).config(function($provide) {
// 利用decorator 修改 Mail
$provide.decorator('Mail', function($delegate) {
$delegate.addCC = function(cc) {
this.cc.push(cc);
};
$delegate.aaa = 'baby';
return $delegate;
});
})
.controller('TestCtrl', function($scope, Mail) {
Mail.addCC('jack');
$scope.test = Mail;
console.log(Mail);
});