[英]Angular: Return data only once several promises are fulfilled
I want to return data from a Service function and inject it into a controller via the routeProvider, but only once the data has been fully loaded. 我想从Service函数返回数据,并通过routeProvider将其注入到控制器中,但是只有在数据完全加载后才可以。
app.js: 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: 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;
});
});
}
}
});
Controller: 控制器:
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;
...
Currently I have the problem that the value is injected before "model" is fully loaded. 当前,我遇到的问题是,在“模型”完全加载之前已注入值。 I tried to pack the subqueries into a $q.all promise, but I don't know exactly where to go from there
我试图将子查询打包成$ q.all的承诺,但我不知道从那里到底要去哪里
Any help would be appreciated 任何帮助,将不胜感激
You want to use $q.defer() and returned the deferred promise object. 您要使用$ q.defer()并返回延迟的Promise对象。 You code will look something like this.
您的代码将如下所示。
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();
}
});
EDIT As others have mentioned you need to pass your array of promises into $q.all to get this to work right. 编辑正如其他人提到的那样,您需要将您的诺言数组传递给$ q.all,以使其正常工作。 Also it's worth noting that $q.all will return an array with the results of each promise in the order they were in the promise array.
同样值得注意的是,$ q.all将返回一个数组,其中每个promise的结果按照它们在promise数组中的顺序排列。
Here's a plunker demoing the use of defer . 这是一个演示defer用法的小伙子 。
There's more $q.defer and $q.all here in the Angular's Docs . Angular的Docs中还有更多的$ q.defer和$ q.all。
You will need to use $q.all
with array of promises and return it from outer promise: 您将需要将
$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;
});
});
}
}
});
You are not using $q.all
correctly. 您没有正确使用
$q.all
。 The simplest possible fix to your code would be changing 对代码的最简单的修复可能就是更改
$q.all(function () {
return model;
});
to 至
$q.all(promises).then(function() {
return model;
});
You're basically not "telling" $q.all
which promises it needs to aggregate. 您基本上不是在“告诉”
$q.all
,这保证它需要汇总。 Please refer to the documentation for $q and check how all
works. 请参阅$ q的文档,并检查
all
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.