我需要编写访问后端数据的代码。
麻烦的是后端还没有准备好。所以我想注入一个服务,可能通过配置,使用真正的后端或模拟对象。
我认为角度服务是我需要的。但我不清楚如何实现这一点。
app.factory('myService', function() {
var mySrv;
//if backend is live, get the data from there with $http
//else get data from a mock json object
return mySrv;
});
不知怎的,我想我必须再写两个服务,真正的服务和假服务,然后在'myService'中调用其中一个服务?
也许我完全误解了嘲讽,但我宁愿不要为测试运行而嘲笑它(不适用于这篇文章中的单元测试:Injecting a mock into an AngularJS service - 我希望应用程序真正使用我的模拟用于演示和开发目的。
答案 0 :(得分:1)
这实际上是Angular的依赖注入系统真正派上用场的地方。 Angular中的所有内容在某种程度上基本上都是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
,它都将使用您根据配置提供的模拟服务。
您可以在下面的代码段中看到完整工作示例。
(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>
答案 1 :(得分:0)
这需要是一项服务吗?如果你想创建一个模拟服务,那么Josh的上述答案是完美的。
如果您不喜欢使用某项服务,那么我建议您查看以下问题Mock backend for Angular / Gulp app的答案,该问题也是关于嘲笑后端的问题。无论你的后端是创建的还是没有嘲笑它,都可以让你更加稳定的测试运行和app的开发。