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

cer*_*eny 7 javascript ajax jquery angularjs

有没有办法通过get()AngularJS中的函数调用对URL的未知数量的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;
}
Run Code Online (Sandbox Code Playgroud)

我检查是否有任何UID,并为每个我创建一个temp对象,其中填充了uid一个accountInfo对象,然后是一个files对象.设置完temp对象后,我将其推入myDropbox阵列.循环完成后,我将dropboxAccounts模型设置为myDropbox变量in $scope.我是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"}]
}
Run Code Online (Sandbox Code Playgroud)

奇怪的是,我的UID中只有一个会更新.我知道循环是正确的,因为我有两个UID,如果我在开始时警告循环,我得到两个循环.我认为第二个没有被填充的原因是因为推送声明不等待两个承诺通过.我怎样才能确保我等待每一个AJAX调用的分配之前完成myDropbox$scope变量?

cer*_*eny 15

介绍

我是很新,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);
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

基本算法

我们首先声明一个模块myApp并将其保存在变量中app...注意我们传递的空数组,这通常是任何进一步要求的参数,这些要求可能会或可能不会从其他模块继承.

声明我们的模块之后,我们需要创建一个相应的控制器,它将成为所有交互发生的网关.在这种情况下,我们需要访问$scope相对于我们的控制器的变量(而不是相对于应用程序本身).我们还宣布这个控制器与哪个工厂有关,就我而言dropbox(我们马上就到了工厂).在这个控制器里面我们分配两个模型$scope:dropboxAccountsdropboxFiles.请注意,我最初的愿望是在我的AngularJS应用程序中有一个模型.虽然这是可能的......我选择反对它,因为我发现很难区分我的两种类型的JSON返回.一个返回帐户元数据,另一个返回该帐户的文件数组.我希望将所有这些都放在一个模型下并按uid参数排序,但发现如果不改变我的RESTful端点输出的JSON,这是不可能的.最后,我选择了两个单独的模型,这样我就可以更轻松地使用它们(直到我找到一种方法根据一个公共参数组合它们).

最后,我们创建了一个存储我的AJAX函数的工厂($http用于实际的AJAX调用,以及$q处理promises).我有两个功能:(记住从我的控制器调用)getAccountsgetFiles.他们每个人都有一个名为promises的数组,它将存储我的$http呼叫的承诺.我在for循环中运行这些调用,它将查看我的每个项目theUIDS,它在我的AJAX调用中使用,然后被推送到promises数组.最后,我们$q将等待,直到promises数组中的所有AJAX调用都成功完成,然后将一个大承诺中的所有数据返回给我们的控制器并分配给它$scope.

我学到的是

AngularJS非常强硬.这个特殊问题需要我两天的调试和反复尝试.有人告诉我,虽然这个前端MVC框架的学习曲线非常陡峭,但是回报非常值得.我想我们会看到......

资源