使用角度中的$ q同时检索多个数据

时间:2013-09-06 14:19:37

标签: angularjs

民众..

我需要在程序开始时从大约8个差异资源中检索数据。

这些资源彼此独立可以并行调用。 (即我不需要一个数据来确定从另一个资源中检索什么)

然而,未来任何事情都需要确保我拥有来自所有资源的所有数据,因为它们相互操作。

所以在我的控制器的开头,我使用以下代码调用init函数:

* 编辑更具体地说,我的确切代码如下所示

$scope.init = function () {
    return $q.all([
    Factory1.getCarData.query(), // returns a resource object like [$resolved: false, $then: function]
    Factory2.getOtherData.query(), // returns a resource object like [$resolved: false, $then: function] 
    Factory3.getSomeOtherData.query() // returns a resource object like [$resolved: false, $then: function]
    ....,
    resource8.query()]).then(result) {
        $scope.data1 = result[1];
        $scope.data2 = result1[2];...
        $scope.data8 = result[3];

        console.log($scope.data1); //prints as [$resolved: false, $then: function]
        console.log($scope.data1[1]);
        prints as undefined

        doSomethingonData1($scope.data2);
        doSomethingonData2($scope.data3, $scope.data4);..etc etc
    }
}

其中Factory1定义为:

angular.module('app').factory('Factory1', function (Factory1Resource)  {    
   var carPromise = Factory1Resource.query(); 
    return {
      getCarData: function(){ return carPromise;}
    }

和Factory1Resource定义为:

.factory('Factory1Resource', ['$resource', function($resource) {
    return $resource(myURL, {}, {} );
  }])

使用工厂的重点是确保所有8个资源的数据操作都在控制器外部以单个单位进行。

我的观点是......我认为只有在所有资源都解决后才会调用“.then”函数。这意味着我的变量$ scope.data1,$ scope.data2等应该具有实际数据而不是资源对象。

当我执行console.log($ scope.data1)时,情况并非如此..它打印为[$ resolved:false,$ then:function]

这打破了程序的流程。

现在我以为我已经做了很多关于承诺和资源的阅读,我现在是一个开明的人,但显然我在这里缺少一些东西。

我想要的是我的变量($ scope.data1,$ scope.data2等)都包含实际数据。

任何提示?或者,我可以随意提出一些关于如何布置代码的更好的想法。

3 个答案:

答案 0 :(得分:0)

then()需要一个函数,就像这样做

.then(function(result) {
    $scope.data1 = result[1];
    ...
});

为您创建了一个演示,我简化了一些代码。它工作正常。 Demo

答案 1 :(得分:0)

@sza非常感谢你的建议和帮助。这似乎是正确的方法,但有一个傻瓜证明系统,我做了以下:

在所有".then"的{​​{1}}部分设置标记 - 现在代码如下:

Factory.getData.query()

在此之后,我会监视所有标志,一旦所有标志变为真,我就开始进行其余的处理。我再次不知道这是否是正确的方法,但它确实似乎是有效的。

再次感谢大家的意见。

答案 2 :(得分:-1)

不是将resource.query返回的对象直接传递给$q.all(,而是应该传递resource.query().$promise

根据angular $ resource文档

  

资源实例和集合具有这些附加功能   属性:

     

$ promise:创建的原始服务器交互的承诺   这个实例或集合。

http://docs.angularjs.org/api/ngResource。$资源

<强>更新

我决定使用我开发的现有应用程序自己创建测试。我要粘贴适合我的代码。也许你在调用资源时有不同的结构:

 $provide.factory('GenericResource', ['$resource','$q', function($resource,$q){
        var AccountResource = $resource('/user/accounts/balances'),
            BankResource = $resource('/banks');

        $q.all([AccountResource.query().$promise, BankResource.query().$promise]).then(function(data){
            console.log(data);
        });
    }]);

console.log的输出是:

[
Array[3]
    0: Resource
    1: Resource
    2: Resource
    $promise: Object
    $resolved: true
    length: 3
    __proto__: Array[0]
, 
    Array[4]
    0: Resource
    1: Resource
    2: Resource
    3: Resource
    $promise: Object
    $resolved: true
    length: 4
    __proto__: Array[0]
]

正如您所看到的,返回的数据包含3个和4个表示所提取数据的资源对象。这个结果与你的结果相似吗?