簡體   English   中英

Angular:僅在滿足幾個承諾后才返回數據

[英]Angular: Return data only once several promises are fulfilled

我想從Service函數返回數據,並通過routeProvider將其注入到控制器中,但是只有在數據完全加載后才可以。

app.js:

    .when('/sources', {
        templateUrl: 'views/app/source/inventory.html',
        controller: 'InventoryCtrl',
        pageTitle: 'Data Inventory',
        resolve: {
            orders: function (OrderService) {
                return OrderService.getOrders();
            },
            sources: function (SourceService) {
                return SourceService.getSources();
            }
        }
    })

SourceService:

angular.module('wp.source')
.factory('SourceService', function ($http, $q) {
    return {
        getSources: function () {
            var model = {
                sources: []
            };
            var promises = [];
            return $http.get('datasets/project.json')
                .then(function (data) {
                    if(localStorage['files'] != null) {
                        var files = JSON.parse(localStorage['files']);
                        for (var i = 0; i < files.length; i++) {
                            model.sources.push(files[i]);
                        }
                    }
                    var sources = [];
                    for (var sourceId in data.data.sources) {
                        var source = data.data.sources[sourceId];
                        source.id = sourceId;
                        sources.push(source);
                    }


                    angular.forEach(sources, function (source) {
                        promises.push($http.get('datasets/' + source.filename).then(function (datasource, resolve) {
                            var metadata = datasource.data.metadata;
                            var source = {
                                name: metadata.name,
                                address: metadata.url,
                                frequency: metadata.refresh,
                                type: metadata.type,
                                tags: metadata.tags,
                                size: metadata.size,
                                active: source.active,
                                sourceID: source.id,
                                sourceFile: source.filename
                            };
                            return source;
                        }));
                    });

                    //var finalPromise = sources.reduce(function (promise, source, index, array) {
                    //    return promise.then(function (a) {
                    //        var query = $http.get('datasets/' + source.filename)
                    //            .then(function (datasource) {
                    //                var metadata = datasource.data.metadata;
                    //                model.sources.push({
                    //                    name: metadata.name,
                    //                    address: metadata.url,
                    //                    frequency: metadata.refresh,
                    //                    type: metadata.type,
                    //                    tags: metadata.tags,
                    //                    size: metadata.size,
                    //                    active: source.active,
                    //                    sourceID: source.id,
                    //                    sourceFile: source.filename
                    //                });
                    //            });
                    //    });
                    //}, $q.when([]));
                    //
                    //finalPromise.finally(function () {
                    //    return model;
                    //})
                    $q.all(function () {
                        return model;
                    });
                });

        }
    }
});

控制器:

angular.module('wp.source')
.controller('InventoryCtrl', function ($scope, orders, sources) {
    $scope.orders = orders.data;

    $scope.gridView = true;
    $scope.rowView = false;

    $scope.allSources = sources.sources;
    $scope.shownSources = $scope.allSources;
...

當前,我遇到的問題是,在“模型”完全加載之前已注入值。 我試圖將子查詢打包成$ q.all的承諾,但我不知道從那里到底要去哪里

任何幫助,將不勝感激

您要使用$ q.defer()並返回延遲的Promise對象。 您的代碼將如下所示。

angular.module('wp.source')
.factory('SourceService', function ($http, $q) {
    return {
        getSources: function () {
            var model = {
                sources: []
            };
            var deffered = $q.defer();
            var promises = [];
            return $http.get('datasets/project.json')
                .then(function (data) {
                    if(localStorage['files'] != null) {
                        var files = JSON.parse(localStorage['files']);
                        for (var i = 0; i < files.length; i++) {
                            model.sources.push(files[i]);
                        }
                    }
                    var sources = [];
                    for (var sourceId in data.data.sources) {
                        var source = data.data.sources[sourceId];
                        source.id = sourceId;
                        sources.push(source);
                    }


                    angular.forEach(sources, function (source) {
                        promises.push($http.get('datasets/' + source.filename).then(function (datasource, resolve) {
                            var metadata = datasource.data.metadata;
                            var source = {
                                name: metadata.name,
                                address: metadata.url,
                                frequency: metadata.refresh,
                                type: metadata.type,
                                tags: metadata.tags,
                                size: metadata.size,
                                active: source.active,
                                sourceID: source.id,
                                sourceFile: source.filename
                            };
                            return source;
                        }));
                    });

                    //var finalPromise = sources.reduce(function (promise, source, index, array) {
                    //    return promise.then(function (a) {
                    //        var query = $http.get('datasets/' + source.filename)
                    //            .then(function (datasource) {
                    //                var metadata = datasource.data.metadata;
                    //                model.sources.push({
                    //                    name: metadata.name,
                    //                    address: metadata.url,
                    //                    frequency: metadata.refresh,
                    //                    type: metadata.type,
                    //                    tags: metadata.tags,
                    //                    size: metadata.size,
                    //                    active: source.active,
                    //                    sourceID: source.id,
                    //                    sourceFile: source.filename
                    //                });
                    //            });
                    //    });
                    //}, $q.when([]));
                    //
                    //finalPromise.finally(function () {
                    //    return model;
                    //})
                    $q.all(promises).then(function () {
                        deferred.resolve(model);
                    });
                });
        }
          return deferred.promise();
    }
});

編輯正如其他人提到的那樣,您需要將您的諾言數組傳遞給$ q.all,以使其正常工作。 同樣值得注意的是,$ q.all將返回一個數組,其中每個promise的結果按照它們在promise數組中的順序排列。

這是一個演示defer用法的小伙子

Angular的Docs中還有更多的$ q.defer和$ q.all。

您將需要將$q.all$q.all數組一起使用,並從外部promise返回它:

angular.module('wp.source')
.factory('SourceService', function($http, $q) {
    return {
        getSources: function() {
            var model = {
                sources: []
            };
            return $http.get('datasets/project.json').then(function(data) {

                if (localStorage['files'] != null) {
                    var files = JSON.parse(localStorage['files']);
                    for (var i = 0; i < files.length; i++) {
                        model.sources.push(files[i]);
                    }
                }

                var sources = [],
                    promises = [];

                for (var sourceId in data.data.sources) {
                    var source = data.data.sources[sourceId];
                    source.id = sourceId;
                    sources.push(source);
                }

                var promises = sources.map(function(source) {
                    return $http.get('datasets/' + source.filename).then(function(datasource, resolve) {
                        var metadata = datasource.data.metadata;
                        model.sources.push({
                            name: metadata.name,
                            address: metadata.url,
                            frequency: metadata.refresh,
                            type: metadata.type,
                            tags: metadata.tags,
                            size: metadata.size,
                            active: source.active,
                            sourceID: source.id,
                            sourceFile: source.filename
                        });
                    });    
                });

                return $q.all(promises).then(function() {
                    return model;
                });
            });

        }
    }
});

您沒有正確使用$q.all 對代碼的最簡單的修復可能就是更改

$q.all(function () {
    return model;
});

$q.all(promises).then(function() {
    return model;
});

您基本上不是在“告訴” $q.all ,這保證它需要匯總。 請參閱$ q文檔,並檢查all

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM