我在单独的.js文件中为前端后端环境编写了这个小代码。只要有一个ajax调用myfile.json
,我就需要/somelink
。
angular.module('myApp')
.config(function($provide) {
$provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
})
.run(function($httpBackend, $http) {
$httpBackend.whenGET('/somelink').respond(function(method, url, data) {
$http({method: 'GET', url: '/somelink/myfile.json'})
.success(function(data, status, headers, config) {
return data;
})
.error(function(data, status, headers, config) {
});
});
});
但是这段代码不起作用并且给了我错误:
Error: Unexpected request: GET /somelink/myfile.json
有人可以帮我解决这个问题吗?
请注意,我不想直接调用$ http来获取代码中的.json文件,因为这会丢弃生产代码。这样做的目的是将此代码分别保留在后端开发中。
感谢。
更新1:
我补充说:
$rootScope.$apply();
$httpBackend.flush();
现在我还有另一个错误:Uncaught Error: No pending request to flush !
更新2:
玩完游戏后,我发现了一个小黑客。我把它放在.run()
所有其他$ httpBackend模拟之前。此.js
文件也必须放在所有控制器/服务/指令之前和app.js引导程序之后。
var data;
$.ajax({
type: 'GET',
async: false,
url: '/somelink/myfile.json'
}).success(function(res) {
data = res;
}).error(function(data) {
});
然后这个:
$httpBackend.whenGET('/somelink').respond(data);
键是async: false
,这样可以确保将JSON加载到变量data
中。所有这些必须在其他对象触发并调用ajax事件之前发生。这只是前端后端开发的黑客攻击。生产时,当然会删除此.js文件。我不喜欢这么多是因为使用async: false
和直接$.ajax()
代替$http
答案 0 :(得分:8)
以下为我工作没有任何黑客
$httpBackend.whenGET('/endpoint').respond($resource("/path/to.json").query());
礼貌https://groups.google.com/d/msg/angular/grbwk-VehDE/UBIho6qcmLMJ
答案 1 :(得分:4)
此问题的一个非常干净的解决方案是使用plain vanilla JavaScript
,因为$httpBackend
不会处理asynchronous
请求。
此方法不需要jQuery
代码。
$httpBackend.when('GET', 'http://localhost:3000/api/data').respond(getData());
function getData() {
var request = new XMLHttpRequest();
request.open('GET', '/db/myData.json', false);
request.send(null);
return [request.status, request.response, {}];
}
答案 2 :(得分:3)
我知道这是一个迟到的回应,但会分享我的经验,希望能为未来的同行提供一些帮助。
由于这个非常有用的blog post,我成功地实现了一个有效的模拟后端。
首先,我将所有端点作为常量放在一个位置,以便只定义它们一次,并在模拟的后端,在我的测试中显示它们,显然在所有负责AJAX调用的服务中。
angular.module('appName.urls', [])
.constant('API_endpoints', {
login: 'authentication/login',
logout: 'authentication/logout',
signUp: 'authentication/signup',
userList: 'users/list'
});
然后我将ngMockE2E
添加为整个应用程序的依赖项。
angular.module('appName', [
'ui.router',
...
'ngMockE2E'
])
然后我为实际的模拟后端创建了一个文件,让我们称之为fakeBackend.js
并在index.html
中引用。这个文件取自上面的链接,但这是我实现的一个简化示例(这里提供模拟登录):
angular.module('appName').run(function($httpBackend, API_endpoints) {
var credentials = {
email : 'a@a.a',
password : '12345'
};
$httpBackend.whenPOST(API_endpoints.login)
.respond(function(method, url, data) {
var req = JSON.parse(data),
res;
// very light credential check...
if(req.email === credentials.email && req.password === credentials.password ){
// generate a successful response
res = [200, {uuid:1}, {}];
} else {
// generate an error if credentials are wrong
res = [400, {}, {}];
}
return res;
});
// Respond to all templates request
// Every file in states/ folder will be served automatically
$httpBackend.whenGET(/states\//).passThrough();
}):
另请注意,我的states
文件夹中的所有内容都提供了最后一行,我的所有模板都驻留在该文件夹中。这显然是一个非常简单的例子,但博客文章作者也分享了一个非常详细和有用的plunkr。
答案 3 :(得分:2)
我(以及其他许多人)在使用$ httpBackend进行测试时遇到了这个问题。我还没有将它用于后端开发。测试中的解决方案是:
在我的测试中让$ http工作我必须
root.$apply();
httpBackend.flush();
也许这样的事情可以帮到你。
答案 4 :(得分:1)
@Aakash Shah使用原始javascript制作同步xhr请求的答案对我来说非常有效。这里有一些代码来澄清我如何概括它。
addMock('/ mocks / json / myjson.json',new RegExp('yada /.*/ getMyJson'));
function addMock(jsonFilePath, urlToReplace) {
$httpBackend.whenGET(urlToReplace)
.respond.apply(this, getData(jsonFilePath)); // apply to put the parameters as args
}
function getData(jsonFilePath) {
var request = new XMLHttpRequest();
request.open('GET', jsonFilePath, false);
request.send(null);
return [request.status, request.response, {}];
}