我的目标是获取一系列图像URL(从API获取,设置其CORS标头)并循环遍历它,使用xhr获取每个图像,在canvas元素中调整其大小,然后生成另一个数组,其条目是调整大小的图像的数据。我的问题是只有数组中的最后一个条目被正确处理,其他一切都是空白图像 - 我的猜测是$ q.deferred()在循环的每次迭代中被覆盖,但我不是真的知道,因为我是承诺和异步的新手。另外,我在AngularJS v1.25中写这篇文章。您可以在http://codepen.io/anon/pen/razwyZ?editors=101查看我的代码。我也会在这里发布:
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
myApp.controller('MyCtrl', ['$scope', '$q',
function($scope, $q) {
resizeImage = function(imgSrc) {
var deferred = $q.defer();
// console.log(imgSrc);
// console.log("resizing image");
image = new Image();
image.src = imgSrc;
image.onload = function() {
var canvas = document.createElement("canvas");
canvas.height = 300;
canvas.width = 300;
var ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, 300, 300);
deferred.resolve(canvas.toDataURL("image/png"));
};
return deferred.promise;
};
fetchImage = function(src) {
var deferred = $q.defer();
var xhr = new XMLHttpRequest();
xhr.responseType = 'blob';
xhr.onload = function() {
var url = URL.createObjectURL(xhr.response);
image = new Image();
resizeImage(url)
.then(function(dataUri) {
deferred.resolve(dataUri);
});
};
xhr.open('get', src);
xhr.send();
console.log(deferred.promise);
return deferred.promise;
};
$scope.picUrls = ["https://res.cloudinary.com/mediocre/image/upload/v1415293060/od9rkw2xtdtfsfiblq6k.png", "https://res.cloudinary.com/mediocre/image/upload/v1415293108/pgnbdgx0aamspgcxzwmx.png", "https://res.cloudinary.com/mediocre/image/upload/v1415294024/z7ohumjr5vs87e1nn5fl.png", "https://res.cloudinary.com/mediocre/image/upload/v1422407613/mzuce3ooqpcewddq9iih.png"];
$scope.picArray = [];
for (i = 0; i < $scope.picUrls.length; i++) {
console.log("executing loop")
$scope.picArray.push(fetchImage($scope.picUrls[i]));
}
$q.all($scope.picArray).then(function(imgArray) {
console.log("executing q.all statement");
$scope.picArray = imgArray;
console.log($scope.picArray);
});
}
]);
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="pic in picArray">
<img src="pic">
</div>
</div>
</body>
</html>
答案 0 :(得分:0)
你实际上正确地做了延期的承诺。我不知道为什么你使用$q.defer()
和xhr
时,你刚刚使用了$http.get
,它已经返回了一个承诺。
你有两个小问题:
1)你应该使用ng-src
而不是src
,表达式应该在花括号中。如果没有ng-src
,浏览器将尝试从位置"/{{pic}}"
下载。
2)由于数组包含重复条目,因此ng-repeat
出错。要解决此问题,您需要添加track by
(通常,为了查看更好的错误,请从.min
移除angular.min.js
。
<div ng-repeat="pic in picArray">
<img ng-src="{{pic}}">
</div>
修改强>
你还有一些问题。
1)在您的resizeImage
和fetchImage
中,您忘记在本地声明image
变量,因为您没有使用"use strict"
(一个坏主意就在那里)您已经有效地创建了一个全局image
变量。
将其更改为:
var image = new Image();
2)不要重复使用存储promises的数组来存储图像。这会生成失败的HTTP请求以检索图像的src
。
使用其他变量:
$scope.pics = [];
// then in `$q.all`
$scope.pics = imgArray;
和ng-repeat
:
<div ng-repeat="pic in pics track by $index">
<img ng-src="{{pic}}">
</div>