这实际上是 Angular 的依赖注入系统真正派上用场的地方。 在某种程度上,Angular 中的一切基本上都是provider。 服务和工厂等方法只是避免样板代码的便利功能。
可以在引导过程中配置提供程序,这对于设置与您描述的完全一样的场景非常方便。
在最简单的情况下,provider 只需要是一个构造函数,它使用 $get 函数创建一个对象。 $get 是创建实际服务的地方,您可以在这里查看要创建的服务。
//A simple provider
function DataServiceProvider(){
var _this = this;
_this.$get = function(){
//Use configured value to decide which
// service to return
return _this.useMock ?
new MockService() :
new RealService;
};
}
现在您可以将其注册为应用程序模块的提供程序。
angular.module('my-module', [])
.provider('dataService', DataServiceProvider);
并且提供者可以在创建第一个服务实例之前进行配置。 按照惯例,提供者的身份为NAME + 'Provider'
angular.module('my-module')
.config(['dataServiceProvider', function(dataServiceProvider){
//Set the flag to use mock service
dataServiceProvider.useMock = true;
}]);
现在,每当您在应用程序的任何位置注入 dataService 时,它都会使用您根据配置提供的模拟服务。
您可以在下面的 sn-p 中看到一个完整的工作示例。
(function(){
function RealService(){
this.description = 'I\'m the real McCoy!';
}
function MockService(){
this.description = 'I\'m a shady imposter :P';
}
function DataServiceProvider(){
var $this = this;
$this.useMock = false;
$this.$get = function(){
return $this.useMock ?
new MockService() :
new RealService();
};
}
function CommonController(dataService){
this.dataServiceDescription = dataService.description;
}
CommonController.$inject = ['dataService'];
angular.module('common', [])
.provider('dataService', DataServiceProvider)
.controller('commonCtrl', CommonController);
angular.module('provider-app-real-service', ['common'])
.config(['dataServiceProvider', function(dataServiceProvider){
dataServiceProvider.useMock = false;
}]);
angular.module('provider-app-mock-service', ['common'])
.config(['dataServiceProvider', function(dataServiceProvider){
dataServiceProvider.useMock = true;
}]);
var moduleNames = ['provider-app-real-service','provider-app-mock-service'];
angular.forEach(moduleNames, function(modName){
//Have to manually bootstrap because Angular only does one by default
angular.bootstrap(document.getElementById(modName),[modName]);
});
}());
<script src="http://code.angularjs.org/1.3.0/angular.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="container">
<div class="row" id="provider-app-real-service">
<div class="col-sm-12" ng-controller="commonCtrl as ctrl">
<h1>{{ctrl.dataServiceDescription}}</h1>
</div>
</div>
<div class="row" id="provider-app-mock-service">
<div class="col-sm-12" ng-controller="commonCtrl as ctrl">
<h1>{{ctrl.dataServiceDescription}}</h1>
</div>
</div>
</div>