通过调用AWS S3存储桶中的listObjects函数来加载我的页面。这基本上是一个异步调用,它在AWS S3中获取了一堆对象。
如果我将此调用放在控制器中,然后执行$ scope。$ apply(),当异步调用返回并处理完所有数据时,这可以正常工作。
但是,每个页面基本上必须对S3存储桶进行相同的调用以填充页面,所以我基本上将相同的代码粘贴到每个控制器上。
显而易见的事情是将此代码移动到服务中,但如何通过服务更新控制器中的范围?我不能在我的服务中使用$ scope。$ apply()。
如何让调用该服务的控制器知道异步调用已完成处理并更新控制器中的$ scope变量?
感谢您的帮助。
答案 0 :(得分:2)
我建议使用Promises
和Angular $q
服务。为此,只需创建一个返回Promise的服务函数。然后,您可以在Controller中等待此Promise,如果它得到解决,您可以将响应分配给Controller的$scope
。
plunkr(检查开发工具)
我创建了一个简单的演示:
var app = angular.module('demo', []);
app.controller('demoCtrl', function(demoService) {
var self = this;
self.init = init;
self.list = {};
init();
function init () {
console.log("call async Service Method");
demoService.getListObjects()
.then(function (list) {
console.log("received", list);
// Assign Response to the Scope
self.list = list;
});
}
});
app.service('demoService', function($q) {
var self = this;
self.getListObjects = getListObjects;
function getListObjects() {
var deferred= $q.defer();
// Simulate Async Action
setTimeout(function () {
var list = {};
deferred.resolve(list);
}, 1000);
return deferred.promise;
}
});
答案 1 :(得分:0)
您可以从Service方法返回一组对象,并在控制器调用方法中对其进行分配。
服务:
angular
.module('app')
.service('servS3', servS3);
function servS3()
{
var service = {
gets3List = gets3List
};
return service;
function gets3List(){
//Write your logic and return array of s3 List
};
}
控制器:
$scope.s3ListObject = [];
servS3.gets3List()
.then(function(response){
$scope.s3ListObject = response.data;
});
此外,如果可以进行缓存,请尝试在登录期间缓存此S3Data(在sessionStorage上),而不是每次都加载可能影响性能的数据。