我试图显示从服务器下载文件的进度,为此我将以下代码放入指令中:
var app = angular.module('app', ['ui.bootstrap']);
app.controller('downloadCtrl', function($scope) {
$scope.disabled = false;
let ctrl = this;
ctrl.download = function(response) {
let file = response.data;
let fileName = response.headers('Content-Disposition').match(/filename(?:(?:\*=UTF-8'')|(?:=))(.*)/)[1];
let fileReader = new FileReader();
fileReader.onloadstart = () => {
$scope.apply(function() {
$scope.disabled = true;
});
};
fileReader.onload = function() {
let blob = new Blob([new Uint8Array(this.result)], {
type: file.type
});
let objectUrl = URL.createObjectURL(blob);
let a = document.createElement('a');
a.download = decodeURI(fileName.replace(/[\"]/gi, ''));
a.href = objectUrl;
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
URL.revokeObjectURL(objectUrl);
$scope.$apply(function() {
$scope.disabled = false;
});
}, 2000);
};
fileReader.onprogress = data => {
console.log(data);
if (data.lengthComputable) {
let progress = parseInt(((data.loaded / data.total) * 100), 10);
console.log(progress);
$scope.$apply(function() {
$scope.progress = progress;
});
}
};
fileReader.readAsArrayBuffer(file);
};
});
app.directive('download', function($http) {
return {
restrict: 'EA',
templateUrl: 'download.html',
scope: {},
controller: 'downloadCtrl',
link: function(scope, element, attrs, controller) {
element.on('click', function(){
let url = 'https://github.com/angular-ui/bootstrap/archive/master.zip';
console.log(url);
$http.get(url).then(response => {
console.log(response);
controller.download(response); });
})
}
};
});
.btn > .progress {
margin-bottom: 0;
width: 100px;
}
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-animate.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular-touch.js"></script>
<script src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-2.5.0.js"></script>
<script type="text/ng-template" id="download.html">
<button class="btn btn-default" ng-disabled="disabled">
<span class="glyphicon glyphicon-download-alt" ng-hide="disabled"></span>
<span uib-progressbar class="progress-striped active" value="progress" ng-show="disabled"></span>
</button>
</script>
</head>
<body ng-app="app">
<div class="container">
<div class="panel panel-default">
<div class="panel-body">
<download></download>
</div>
</div>
</div>
</body>
</html>
这段代码有效,但有一个小缺点:我们打开开发者控制台并观察执行过程:
- 对服务器接收文件的请求正在等待中。
- 收到服务器的响应,在开发者控制台中可以看到正在接收文件(进度条尚不可见)
- 当进度达到 50..75%(目测,来自开发者控制台)时,会出现一个进度条,然后一切正常。
在事件处理程序中向控制台添加onprogress输出,接收到文件后,控制台中出现进度值:12,17,31,45,59,74,78,92,100
告诉我我做错了什么,为什么在开始下载文件后没有立即显示进度条?
PS:在最近版本的 Firefox 和 Chrome 中重复该行为
看来您的问题出在其他地方。
因为原则上一切正常。注意,
fileReader.onprogress不必对每个百分比都进行。它在一条数据到达时执行。如果数据量不大,那么一般可以调用2次,例如。还添加了来自服务器的文件下载事件的示例。
jsfiddle上的示例。