我已经写了一个处理上传到S3的Angular工厂:
'use strict';
angular.module('myApp.s3', [])
.factory('S3', function ($q) {
var aws = { ... }
var progress = 0;
function getFileName(fileURI) {
return fileURI.split('/').pop();
}
return {
progress: progress,
upload: function (fileKey, fileURI, mimeType) {
var fileName = getFileName(fileURI);
if (fileName === '') {
console.log('File name can\'t be empty');
return;
}
var defer = $q.defer();
defer.promise.then(function (event) {
alert(JSON.stringify(event));
console.log(event);
}, function (error) {
alert(JSON.stringify(error));
console.log(error);
});
var fileTransfer = new FileTransfer();
var fileUploadOptions = new FileUploadOptions();
fileUploadOptions.fileKey = 'file';
fileUploadOptions.fileName = fileName;
fileUploadOptions.chunkedMode = false;
fileUploadOptions.params = {
'key': fileKey,
'AWSAccessKeyId': aws.access_key_id,
'acl': aws.acl,
'policy': aws.policy,
'signature': aws.signature
};
fileTransfer.upload(fileURI, encodeURI('https://' + aws.bucket + '.s3.amazonaws.com/'),
defer.resolve, defer.reject, fileUploadOptions);
fileTransfer.onprogress = function (progressEvent) {
if (progressEvent.lengthComputable) {
progress = (progressEvent.loaded / progressEvent.total) * 100;
console.log(progress);
} else {
//loadingStatus.increment();
}
};
return defer.promise();
}
};
});
此代码工作正常,文件上传到S3。进度日志也有效。当我在控制器中使用此工厂并将进度绑定到范围时,我在我的范围内看不到进度更新。我想这是因为范围没有得到更新事件。
我已经看到了使用作用域初始化工厂的解决方法,并且在工厂内调用了scope.apply()。我不认为这是在Angular中做到这一点的正确方法,但我也不知道正确的方法。有什么提示吗?
答案 0 :(得分:3)
@Dmitry Tolmachov的答案肯定会有效,但我会使用defer.notify,因为你已经在使用一个承诺,因为使用通知你不需要手动调用摘要周期:
fileTransfer.onprogress = function (progressEvent) {
if (progressEvent.lengthComputable) {
progress = (progressEvent.loaded / progressEvent.total) * 100;
console.log(progress);
defer.notify(progress);
} else {
//loadingStatus.increment();
}
};
然后在你的控制器中使用它.then(成功,错误,通知)
答案 1 :(得分:2)
这里的问题是当调用fileTransfer.onprogress时,它不会启动摘要循环。我强烈推荐这篇文章阅读:http://www.sitepoint.com/understanding-angulars-apply-digest/
至于解决方案,其中一个简单的方法是:
1)将$ rootScope注入工厂:
.factory('S3', function ($q, $rootScope) {
2)手动开始摘要周期:
progress = (progressEvent.loaded / progressEvent.total) * 100;
console.log(progress);
$rootScope.$digest();
这必须解决它。