2012-11-19 49 views
0

我有一個非常奇怪的問題,我們正在構建一個角度應用程序。每當我從下面定義的資源(我可以構建的最簡單的例子)中加載一些數據時,我會返回一些數據以供我用於數據綁定(例如,ng-repeat ='message in message'或者{{message.id}} )但是我永遠不能通過將它作爲一個數組或對象(取決於我使用get({id:myId})或query())來從javascript讀取它。

對它進行迭代只會給我諸如$ 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) 
}; 

在問題的我希望能夠返回一個單一的元素形成已經被取出的集合,但我需要一些方法來處理前的數據準備好所發生的呼叫。

在問題B我想處理一些提取的數據並將結果傳遞給「otherService」,但是我需要一種方法來延遲這種情況,直到數據準備就緒。

+0

你沒有告訴你如何去從JavaScript訪問這些資源,所以它是一個有點難以回答。如何迭代檢索的資源? –

+0

迭代只是一個for(每個)循環的測試。然而,我期望能夠: 警報(消息[1] .id) – martijnve

+0

好的,但仍然會很高興看到確切的代碼,因爲我假設您將對Resource的調用視爲同步調用,而那些是異步的。更多信息在這裏:http://stackoverflow.com/questions/11966252/how-does-the-resource-get-function-work-synchronously-in-angularjs/11966512#11966512 –

回答

1

我只看到這個問題出現在單元測試中,解決它的方法是通過「沖洗」模擬$ httpBackend。

按照API docs

The $httpBackend used in production, always responds to requests with responses asynchronously. If we preserved this behavior in unit testing, we'd have to create async unit tests, which are hard to write, follow and maintain. At the same time the testing mock, can't respond synchronously because that would change the execution of the code under test. For this reason the mock $httpBackend has a flush() method, which allows the test to explicitly flush pending requests and thus preserving the async api of the backend, while allowing the test to execute synchronously.

下面是一些上下文的示例:

// 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); 
    }); 
}); 
+0

這是爲什麼被拒絕?如果@martijnve在結果可用之前嘗試訪問異步調用的結果,則會發生這種情況。我已經看到了問題中描述的確切問題,這是我如何解決它... –

+0

感謝aswer,有關承諾的鏈接是啓發。但是我在我的單位測試中並沒有遇到這個問題,但是在我的常規控制器中。 發生了什麼是我加載我的數據,並立即希望做一些與數據通過js。 基於我你的鏈接我fugured我可以調用然後(myfunc(數據){...})的Message.get()的結果,但這給了我一個錯誤說:「TypeError:Object# has no method'然後'」。 – martijnve

+0

@martijnve我很樂意幫你解決這個問題,但需要確切地知道你想要做什麼。你能在你的問題中發表一些更具體的例子嗎? –

相關問題