多个AngularJS将请求放到一个模型中

Multiple AngularJS get requests into one model

本文关键字:一个 模型 AngularJS 请求 多个      更新时间:2023-09-26

是否有一种方法可以通过AngularJS中的get()函数调用未知数量的API,并将它们全部添加到模型($scope变量)中。到目前为止,我所做的如下:

if(theUIDS != "") {
    var myDropbox = [];
    for(i = 0; i < theUIDS.length; i++) {
        var temp = {};
        temp.uid = theUIDS[i];
        $http({ url: '/dropbox/accounts/get', method: 'GET', params: { uid: theUIDS[i] }}).success(function(acctData) {
            temp.accountInfo = acctData;
        });
        $http({ url: '/dropbox/files/get', method: 'GET', params: { uid: theUIDS[i] }}).success(function(fileData) {
            temp.files = fileData;
        });
        myDropbox.push(temp);
    }
    $scope.dropboxAccounts = myDropbox;
}

我检查是否有任何UID,并为每个UID创建一个temp对象,该对象由uid填充,然后是accountInfo对象,然后是files对象。在我设置了temp对象之后,我将其推入myDropbox数组。循环完成后,我将dropboxAccounts模型设置为$scope中的myDropbox变量。我是Angular的新手,但我很确定这至少是一个正确的想法。幸运的是,我以正确的顺序获得了以下数据:

{"uid":"332879"}
{"uid":"155478421",
    "accountInfo":{
        "country":"US",
        "display_name":"Patrick Cason",
        "name":"Second Dropbox",
        "quota_normal":1174504,
        "quota_shared":0,
        "quota_total":2147483648,
        "referral_link":"https://www.dropbox.com/referrals/NTE1NTQ3ODQyMTk?src=app9-203957",
        "uid":155478421},
    "files":[{
        "created_at":"2013-04-17T15:13:46Z",
        "directory":true,
        "dropbox_user_id":26,
        "fileType":"Folder",
        "id":198,
        "name":"Photos",
        "path":"/Photos",
        "rev":"10edb44f9",
        "size":"-",
        "updated_at":"2013-04-17T15:13:46Z"}]
}

奇怪的是,只有一个UID得到更新。我知道循环是正确进行的因为我有两个UID如果我在循环开始时发出警告,我就会得到两个循环。我认为第二个没有被填充的原因是因为push语句没有等待两个承诺都完成。如何确保在将myDropbox分配给$scope变量之前等待每个AJAX调用完成?

简介

我对AngularJS非常陌生,所以这个解决方案非常像一个正在进行的。我想,既然我努力学习了更多关于它的知识,其他人可能也有同样的处境。话虽如此,我不仅要发布我的答案,还要解释我在代码背后的想法。如果有人觉得答案可以改进,我很乐意得到任何反馈。

下面是我用来让一切正常工作的代码:

var app = angular.module('myApp', []);
app.controller('DropboxCtrl', function($scope, dropbox) {
    $scope.dropboxAccounts = dropbox.getAccounts();
    $scope.dropboxFiles = dropbox.getFiles();
});
app.factory('dropbox', function($http, $q) {
    var theUIDS = [12345,67890];
    return {
        getAccounts: function() {
            var promises = [];
            for(i = 0; i < theUIDS.length; i++) {
                promises.push($http({
                    url: '/dropbox/accounts/get', 
                    method: "GET",
                    params: { uid: theUIDS[i] }
                }));
            }
            return $q.all(promises);
        },
        getFiles: function() {
            var promises = [];
            for(i = 0; i < theUIDS.length; i++) {
                promises.push($http({
                    url: '/dropbox/files/get', 
                    method: "GET",
                    params: { uid: theUIDS[i] }
                }));
            }
            return $q.all(promises);
        }
    }
});

基本算法

我们首先声明一个模块myApp并将其保存在变量app中…请注意我们传递的空数组,它通常是任何进一步需求的参数,可以从其他模块继承,也可以不继承。

在我们的模块声明之后,我们需要创建一个相应的控制器,它将成为所有交互发生的网关。在这种情况下,我们需要访问相对于控制器的$scope变量(而不是相对于应用程序本身)。我们还声明了这个控制器与什么工厂相关,在我的例子中是dropbox(我们将在一会儿得到工厂)。在这个控制器内部,我们将两个模型分配给$scope: dropboxAccountsdropboxFiles。请注意,我最初的愿望是在我的AngularJS应用程序中有一个模型。我选择不使用它,因为我发现很难区分我的两种JSON返回类型。一个返回帐户元数据,另一个返回该帐户的文件数组。我本来想把所有这些都放在一个模型下,并按uid参数排序,但发现如果不改变我的RESTful端点输出的JSON,这是不可能做到的。最后,我选择了两个独立的模型,这样我可以更容易地使用它们(直到我找到一种方法根据一个公共参数将它们组合起来)。

最后,我们创建一个存储AJAX函数的工厂(使用$http进行实际的AJAX调用,使用$q处理承诺)。我有两个函数:(记住从我的控制器调用)getAccountsgetFiles。它们每个都有一个名为promises的数组,用于存储$http调用的promise。我在for循环中运行这些调用,该循环将查看AJAX调用中使用的theUIDS中的每个项,然后将其推入promises数组。最后,我们有我们的$q,它将等待,直到所有的AJAX调用在promises数组已经成功完成之前返回所有的数据在一个大的承诺回到我们的控制器,并将其分配给$scope

我学到了什么

AngularJS真的很难。这个特殊的问题花了我两天的时间调试和一次又一次的尝试。有人告诉我,虽然这个前端MVC框架的学习曲线相当陡峭,但回报是值得的。我想我们会看到……

    <
  • AngularJS API/gh>
  • 工厂与服务比较
  • AngularJS的all方法的良好使用
  • jQuery和AngularJS中AJAX承诺的漂亮解释