我试图通过覆盖服务,在实时模式和原型模式下实现我的角度应用程序工作。作为其中的一部分,当在配置中打开原型模式时,我将停止引导进程,加载模拟服务(js)文件,并恢复引导。
以下是准备演示的简化源代码列表:-
App.js
只有我的应用程序,用于模拟调用服务并显示结果。它还需要StubApp,它的提供将用于覆盖服务。
var app = angular.module('app', ['StubsApp'])
.run([ '$rootScope', 'DataService', function($scope, DataService){
DataService.getData().then(function(data){
$scope.name = data;
});
}]);DataService.js
只是一个简单的服务注册的应用程序。
function DataService($q){
this.getData = function(){
return $q.when('I am Real!!');
}
}
DataService.$inject = ['$q'];
angular.module('app').service('DataService',DataService);Driver.js
只是配置注册,这将设置模拟。
angular.module('app').config(['$provide', 'stubServiceProvider', 'AppConfig', function($provide, stubProvider, AppConfig){
if(AppConfig.StubEnabled){
stubProvider.loadStubsInModule('plunker');
}
}]);StubProvider.js
这公开了一个类似于angular.module的接口来注册存根服务。它还查找具有模拟服务列表的stubs.json,该服务通过停止引导来加载。它还公开了应用程序可以使用stubs.json中的服务设置现有服务重载的提供
var Stubs = {},
modules = [];
function module(moduleName) {
return {
mock: function (func) {
modules.push(func);
}, get: function () {
return modules;
}
};
}
Stubs.module = module;
loadStubs();
function loadStubs() {
window.name = "NG_DEFER_BOOTSTRAP!";
var injector = angular.injector(['ng']);
var $q = injector.get('$q');
var $http = injector.get('$http');
var scripts = [];
$http.get('stubs.json').then(function (result) {
scripts = result.data.map(function (src) {
var script = document.createElement('script');
script.src = src;
script.async = true;
document.head.appendChild(script);
var defered = $q.defer();
script.onload = function () {
defered.resolve();
};
return defered.promise;
});
$q.all(scripts).finally(function () {
angular.element().ready(function () {
angular.resumeBootstrap();
});
});
});
}
//This is the provider which actually will do the overriding
angular.module('StubsApp', []).provider('stubService', function ($provide) {
...... //Code in plunker
});DataService Mock.js
这仅仅是一个模拟,它实际上使用Stubs接口注册模拟Stubs.module('app').mock(MockService),而ctor有一个属性stubFor="serviceName",它告诉这个服务实际上模拟了哪个服务。
function MockService($q, $log){
this.getData = function(){
return $q.when('I am Mock!!');
}
}
MockService.$inject = ['$q', '$log'];
MockService.stubFor="DataService";
Stubs.module('app').mock(MockService);stubs.json
只是一个简单的json文件,它指定了模拟
["DataServiceMock.js"]index.html
<script src="app.js"></script>
<script src="DataService.js"></script>
<script src="Driver.js"></script>
<script src="stubprovider.js"></script>这个很好用。现在的问题是,当我将Driver.js文件移动到服务注册(即DataService.js )之前,它不会再模仿了。在"StubProvider.js“中执行重写的代码的特定部分是
Stubs.module(moduleName).get().forEach(function (mod) {
var serviceName = mod.stubFor;
var ctor = mod;
if (serviceName) {
$provide.service(serviceName, ctor);
}
});下面是一个演示Plnkr,如果您注释掉Driver.js中的行,您可以看到输出将来自真正的服务,或者是来自模拟服务。为了在index.html模式Driver.js中复制DataService.js之前的问题,它不会用MockDataservice覆盖DataService。
发布于 2014-10-31 02:27:18
使用createElement和appendChild DOM方法、script元素的src和onload属性以及AngularJS的bootstrap、element和injector方法:
/* Create script element */
var script = document.createElement('script');
/* Set src */
script.src = "https://ajax.googleapis.com/ajax/libs/angularjs/1.3.1/angular.min.js";
/* Append to head */
document.getElementsByTagName("head")[0].appendChild(script);
function dothis()
{
//local datastore
this.mvvm = {};
//template string
var html = "<div>ID: {{$id}}</div>".replace("|",'"',"g");
//template object
var template = angular.element(html);
//template transformer
var compiler = angular.injector(["ng"]).get("$compile");
//template result
var linker = compiler(template);
//scope object
var scope = angular.injector(["ng"]).get("$rootScope");
//scope binding
var result = linker(scope)[0];
/* Append result to body */
document.body.appendChild(result);
/* Render */
angular.bootstrap(document, ['ng']);
}
script.onload = dothis;
https://stackoverflow.com/questions/25537396
复制相似问题