简体   繁体   English

多个AngularJS将请求转换为一个模型

[英]Multiple AngularJS get requests into one model

Is there a way to call an unknown amount of API calls to a URL via the get() function in AngularJS and add those all into a model ( $scope variable). 有没有办法通过AngularJS中的get()函数调用对URL的未知数量的API调用,并将这些调用全部添加到模型中( $scope变量)。 What I've done thus far is the following: 到目前为止我所做的是以下内容:

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;
}

I check if there are any UID's and for each one I create a temp object which is populated with a uid , then an accountInfo object, and then a files object. 我检查是否有任何UID,并为每个我创建一个temp对象,其中填充了一个uid ,然后是一个accountInfo对象,然后是一个files对象。 After I set up my temp object, I push it onto the myDropbox array. 设置temp对象后,我将其推送到myDropbox数组。 Once the loop has finished, I set the dropboxAccounts model to the myDropbox variable in $scope . 循环完成后,我将dropboxAccounts模型设置为$scopemyDropbox变量。 I'm new to Angular, but I'm pretty sure this is at least the right idea. 我是Angular的新手,但我很确定这至少是正确的想法。 Luckily I'm getting the following data in correct order: 幸运的是,我按正确的顺序得到以下数据:

{"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"}]
}

The strange thing is that only one of my UID's gets updated. 奇怪的是,我的UID中只有一个会更新。 I know that the loop is correctly going through because I have two UID's and if I alert at the beginning the loop I get two loops. 我知道循环是正确的,因为我有两个UID,如果我在开始时警告循环,我得到两个循环。 The reason I think the second isn't being populated is because the push statement isn't waiting for both of the promises to go through. 我认为第二个没有被填充的原因是因为推送声明不等待两个承诺通过。 How can I ensure that I wait for each of the AJAX calls to finish before assigning myDropbox to the $scope variable? 在将myDropbox分配给$scope变量之前,如何确保等待每个AJAX调用完成?

Introduction 介绍

I'm pretty new to AngularJS, so this solution is very much so a work-in-progress . 我是很新,AngularJS,所以这种解决方案非常多这样一个工作正在进行中 I figure that since I've struggled through learning more about it that other people may be in the same position as well. 我认为,因为我一直在努力学习更多关于它的事情,其他人也可能处于相同的位置。 With that said, I'm going to not only post my answer, but also explain my thinking behind the code. 话虽如此,我不仅要发布我的答案,还要解释我在代码背后的想法。 I'd love to get any feedback if anyone feels the answer could be improved any. 如果有人觉得答案可以得到改善,我很乐意得到任何反馈。

Final Code 最终守则

Here's the code I used to get everything working: 这是我用来使一切工作的代码:

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);
        }
    }
});

Basic Algorithm 基本算法

We start by declaring a module myApp and saving it in a variable app ... notice the empty array we're passing which would normally be a parameter for any further requirements which may or may not be inherited from other modules. 我们首先声明一个模块myApp并将其保存在一个变量app ...注意我们传递的空数组,这通常是任何进一步要求的参数,可能会也可能不会从其他模块继承。

After our module is declared we need to create a corresponding controller which will be a gateway for all interactions to take place. 声明我们的模块之后,我们需要创建一个相应的控制器,它将成为所有交互发生的网关。 In this case we need access to the $scope variable which is relative to our controller (not relative to the app itself). 在这种情况下,我们需要访问相对于我们的控制器的$scope变量(不是相对于应用程序本身)。 We also declare what factory this controller is related to, in my case it's dropbox (we'll get to factories in a moment). 我们还宣布这个控制器与哪个工厂有关,在我的例子中它是dropbox (我们马上就会到工厂)。 Inside of this controller we assign two models to $scope : dropboxAccounts and dropboxFiles . 在这个控制器内部,我们为$scope分配了两个模型: dropboxAccountsdropboxFiles Note that my original desire was to have one model within my AngularJS app. 请注意,我最初的愿望是在我的AngularJS应用程序中有一个模型。 While this is possible... I opted against it because I found it difficult to differentiate my two types of JSON returns apart. 虽然这是可能的......我选择反对它,因为我发现很难区分我的两种类型的JSON返回。 One returns account metadata and the other returns an array of files of that account. 一个返回帐户元数据,另一个返回该帐户的文件数组。 I would have liked to have all these under one model and be sorted by a uid parameter, but found this to be impossible to do without changing what JSON my RESTful endpoints output. 我希望将所有这些都放在一个模型下并按照uid参数进行排序,但发现如果不改变我的RESTful端点输出的JSON,这是不可能的。 In the end, I opted for two separate models so I can work with them easier (until I find a way to combine them according to one common parameter). 最后,我选择了两个单独的模型,这样我就可以更轻松地使用它们(直到我找到一种方法根据一个公共参数组合它们)。

Lastly, we create a factory which stores my AJAX functions (using $http for the actual AJAX call, and $q for handling the promises). 最后,我们创建了一个存储我的AJAX函数的工厂(使用$http作为实际的AJAX调用,使用$q来处理promises)。 I have two functions: (which remember are called from my controller) getAccounts and getFiles . 我有两个函数:(记得从我的控制器调用) getAccountsgetFiles Each of them has an array called promises which will store the promises of my $http calls. 他们每个人都有一个名为promises的数组,它将存储我的$http调用的promise。 I run through these calls in a for-loop which will look at each of my items in theUIDS , which is used in my AJAX call, and is then pushed onto the promises array. 我在for循环中运行这些调用,它将查看我在AJAX调用中使用的theUIDS中的每个项目,然后将其推送到promises数组。 At the end we have our $q which will wait until all the AJAX calls in the promises array has finished successfully before returning all that data in one big promise back to our controller and assigning it to $scope . 最后我们得到了$q ,它将等到promises数组中的所有AJAX调用都成功完成,然后将一个大承诺中的所有数据返回给我们的控制器并将其分配给$scope

What I Learned 我学到的是

AngularJS is really tough. AngularJS非常强硬。 This particular issue has taken me two days of debugging and trying again and again. 这个特殊问题需要我两天的调试和反复尝试。 I have been told that while the learning curve to this front-end MVC framework is pretty steep, the payoff is well worth it. 有人告诉我,虽然这个前端MVC框架的学习曲线非常陡峭,但是回报非常值得。 I suppose we shall see... 我想我们会看到......

Resources 资源

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM