手动引导和覆盖配置中的angular服务的问题
Issue with manual bootstrapping and overriding angular services in config
我正试图通过覆盖服务使我的角度应用程序在实时模式和原型模式下工作。作为其中的一部分,当配置中打开原型模式时,我会停止引导进程,加载mock服务(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
只是将设置mocking的配置注册。
angular.module('app').config(['$provide', 'stubServiceProvider', 'AppConfig', function($provide, stubProvider, AppConfig){
if(AppConfig.StubEnabled){
stubProvider.loadStubsInModule('plunker');
}
}]);
StubProvider.js
这公开了一个类似于angular.module
的接口来注册存根服务。它还查找具有通过停止引导加载的模拟服务列表的CCD_ 3。它还公开了一个提供,应用程序可以使用该提供来设置现有服务与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接口注册mock Stubs.module('app').mock(MockService)
的mock,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文件,用于指定mock
["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);
}
});
这是一个Demo Plnkr如果您注释掉Driver.js
中的行,您可以看到输出将来自真实服务,而不是来自模拟服务。为了在DataService.js
之前以index.html模式Driver.js
复制该问题,它不会用MockDataservice覆盖DataService。
为什么配置注册的顺序很重要,配置阶段应该在服务实例化之前运行
是否有更好的模式来确保在恢复引导进程之前加载所有脚本,而不是使用延迟模式。
使用AngularJS:的createElement
和appendChild
DOM方法、script
元素的src
和onload
属性以及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;
- chrome.storage.sync.get未返回值-Angular服务
- AngularJS剑道网格绑定到angular服务webapi-当使用[fromuri]进行解析时,排序总是为null
- 在 Jasmine 测试中无法访问 Angular 服务函数
- 如何使 Angular 服务中的数据通过页面刷新持久化
- 画布在 Angular 服务调用中冻结一秒
- 为什么从 Angular 服务中的对象中删除此元素不起作用
- angular服务中的$http承诺
- 在Angular服务中使用$http时,为什么要返回promise和数据
- Angular 1.5.4服务未定义
- 在Angular服务中使用$http和$q的正确方法
- 如何使用Angular 2服务提供包含指向另一个资源的链接/ids的资源集合
- 从函数内部、类内部、模块内部访问 Angular 服务
- 测试angular服务内部方法调用
- Jasmine Mock使用promise为Angular服务
- 在 Angular 服务中接收函数的未声明变量
- 在 Angular 服务中初始化数据的位置
- 无法在注册为 Angular 服务的 ES6 类中共享对象
- Angular 服务问题 -- 在包含 promise 的服务中返回一个数组
- 使用 Angular 服务并且不更改函数调用中的变量
- 从$cookies检索时,Javascript Arrays 在 Angular 服务中没有功能