我正在构建一个角度应用程序,这是一个非常奇怪的问题。每当我从如下定义的资源(我可以构建的最简单的示例)加载一些数据时,我会得到一些我可用于数据绑定的数据(例如,ng-repeat ='message in messages'或{{message.id}} )但我永远无法通过访问它作为数组或对象从javascript中读取它(取决于我使用get({id:myId})或query())。
迭代它只给我$ get,$ query,$ save等键...但没有实际数据。
app.factory('Message', ['$resource', function($resource) {
return $resource('MY_URL/messages/:id', {id: '@id'});
}]);
app.service('messageService', ['$rootScope', 'Message', function($rootScope, Message) {
var messages = Message.query();
var selectedMessage = null;
var service = {};
service.get = function(id) {
// Problem A (see below for details)
if (arguments.length === 1) return Message.get({id: id});
else return messages;
};
var MenuCtrl = function($scope, Project, messageService, otherService) {
$scope.projects = Project.query();
$scope.messages = messageService.get();
// Problem B (details below)
};
在问题A我希望能够从已经提取的集合中返回单个元素,但是我需要一些方法来处理在数据准备好之前发生的调用。
在问题B,我想处理一些获取的数据并将结果传递给“otherService”,但是我需要一种方法来延迟这个,直到数据准备就绪。
答案 0 :(得分:1)
我只看到了这个问题出现在单元测试中,解决它的方法是“刷新”模拟$ httpBackend。
根据API docs:
生产中使用的$ httpBackend始终以异步方式响应具有响应的请求。如果我们在单元测试中保留了这种行为,我们必须创建异步单元测试,这些测试很难编写,遵循和维护。同时测试模拟,不能同步响应,因为这会改变被测代码的执行。因此,模拟$ httpBackend有一个flush()方法,它允许测试显式刷新挂起的请求,从而保留后端的异步api,同时允许测试同步执行。
这是一个带有某些背景的例子:
// define a resource within a service
angular.module('app.services', ['ngResource'])
.factory('Message', function ($resource) {
var url = ...
, params = ...
, actions = ...;
return $resource(url, params, actions);
}
// Query the resource in a controller
function MessagesCtrl ($scope, $routeParams, Message) {
$scope.messages = Message.query();
}
// unit test with a mocked backend
describe('MessagesCtrl', function() {
var scope, ctrl, $httpBackend, messages;
beforeEach(inject(function (_$httpBackend_, $rootScope, $controller) {
$httpBackend = _$httpBackend_;
scope = $rootScope.$new();
messages = [
{
id: '1',
text: 'foo',
}, {
id: '2',
text: 'foo',
}
]
$httpBackend.expectGET('/api/messages').respond(messages);
ctrl = $controller('MessagesCtrl', {$scope: scope});
}));
it('should get a list of messages', function () {
// THE NEXT LINE WILL SOLVE THE PROBLEM
$httpBackend.flush();
expect(scope.message).toEqualData(message);
});
});