module和provide是用来注册服务到injector中的。查看官方的API,可以看到$provide提供了provide()、constant()、value()、factory()、service()来创建各种不同性质的服务;angular.Module中也提供了这5个服务注册方法。其实2者功能是完全一样的,就是用来向DI容器注册服务到injector中。
对于服务 provide 拥有的方法
provider
factory
service
value
constant
decorator
对于具体实现
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_; }
function factory(name,factoryFn,enforce){ return provider(name,{ $get: enforce !== false ? enforceReturnValue(name,factoryFn):factoryFn }) }
function service(name,constructor){ // return factory(name,['$injector',function($injector){ return $injector.instantiate(constructor); }]) }
function value(name,val){ return factory(name,valueFn(val),false); }
function constant(name,value){ assertNotHasOwnProperty(name,'constant'); providerCache[name] = value; instanceCache[name] = value; }
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); });