我正在研究搜索界面。有一个结果列表视图,每个结果可以“扩展”以显示更多数据。当用户展开结果时,我异步获取可包含0到12张图片的详细信息。这是通过“细节服务”完成的,这是一种角度感的服务。
现在,因为我的目标是“本地化的感觉”并且这些图片可能很重要,所以我不希望它们在完成加载之前出现。
问题是:当每个图像加载时,服务如何通知其客户端(控制器)?
许多文章都建议将promises作为最佳方式。天真地,我会想要返回一个承诺数组 - 每个图像一个 - 将在图像加载后解析。
这似乎是一个严厉的解决方案,需要一个循环将then()函数附加到任意数量的promise。
另一种流行的解决方案是在$ rootScope上使用broadcast()。这看起来“草率”,因为我知道正好谁正在“倾听”结果。
“承诺数组”是正确的,还是更简洁或“有角度”的方式?
注意:这些是独立的结果,不应链接或组成一个承诺。
编辑:为不明确的问题道歉。所需的功能是每张图片在加载时显示。所以聚合承诺是不受欢迎的。这让核心问及承诺是否是最简洁的解决方案。我发现了我认为更好的一个,在答案中表示为延迟显示直到图像加载的图像指令。将此逻辑移出服务并转换为指令似乎是一种更优雅的解决方案。答案 0 :(得分:1)
我会说承诺的一系列承诺'是正确的方法。
您可以使用.all()方法,该方法将任意数量的promise作为参数(作为数组)。然后,您可以将此承诺解决为单一承诺。
返回将使用值的数组/散列解析的单个promise,每个值对应于promises数组/散列中相同索引/键的promise。如果任何承诺通过拒绝得到解决,则此结果承诺将被拒绝并具有相同的拒绝价值。
$q.all([firstPromise.then(function(){
//do something
}),
secondPromise.then(function(){
//do something else
})
])
.then(function(){
//do something after all promises are resolved
});
答案 1 :(得分:0)
promises数组中的每个promise都是并行和异步执行的。 $ q.all让你处理它们都成功解决。
答案 2 :(得分:0)
使用几种方法后,似乎将图像加载检查移动到指令会产生最简洁,可重用和可读的解决方案。
// directive for an "optional background image" element that will only display if and
// after the image loads
.directive('optBgImg',
function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
// create an image object to get a reliable onload event
// (using load on the element unreliable for dynamic divs)
var img = new Image();
// onload handler (on the image, not the element)
img.onload = function() {
img.onload = null;
// add a class to reveal the image
element.addClass("loaded");
// set the background image on the element
// (using background image for advanced formatting)
element.css("background-image", "url(" +
attrs.optBgImg + ")");
};
img.onerror = function() {
img.onerror = null;
// could remove the element here for extra credit
};
// set the source for the image to initiate the load
img.src = attrs.optBgImg;
}
};
});
答案 3 :(得分:0)
你可以写这样的东西(在这个例子中只有$ http.get服务):
var getAllServicesResult = function (servicesList) {
var promises = [];
angular.forEach(servicesList, function (s, index) {
var deffered = $q.defer();
$http.get(s.path, { params: s.params }).success(function (response) {
deffered.resolve(response);
}).error(function (error) {
deffered.reject();
});
promises.push(deffered.promise);
});
return $q.all(promises);
}
servicesList是这样的数组:
servicesList =[{path: '/Reference/GetRefrenceByType'
, params: { refType: d.Service_Ref_Field_Name, baseMapType: 0 }}
,{},...];