My Little World

AngularJs自定义指令实现图片上传

//定义file-Model指令的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MetronicApp.directive('fileModel', ['$parse', function ($parse) {
return {
restrict: 'A',
link: function(scope, element, attrs, ngModel) {
var model = $parse(attrs.fileModel);
var modelSetter = model.assign;
element.bind('change', function(event){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
//附件预览
scope.file = (event.srcElement || event.target).files[0];
scope.getFile();
this.value = ''; //清除已上传的文件,否则无法连续上传相同文件
});
}
};
}
])

//在HTML使用时的代码

1
2
3
4
5
6
7
8
9
10
 <div class="form-group">
<label class="control-label col-md-3">图片上传</label>
<div class="col-md-9 fileinput">
<img src="{{detaildata.banner}}" name="img" style="width:40px;height: 40px;">
<span class="btn red btn-outline btn-file" style="margin-left: 10px;margin-top:0px;">
<span class="fileinput-new"> 重新上传 </span>
<input type="hidden"><input id="upload" type="file" file-model="myFile" name="..." accept="image/*" >
</span>
</div>
</div>

//Controller中上传图片时的js函数

1
2
3
4
5
6
7
8
$scope.getFile = function () {
var postData = {
fileName: $scope.file
};
fileReader.readAsDataUrl($rootScope.settings.url + "", postData).success( function(response) {
$scope.detaildata.banner = response;
});
};

//定义fileReader服务的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
angular.module('MetronicApp')
.factory('fileReader', ["$http", function($http){
var readAsDataURL = function (url, data) {
var fd = new FormData();
angular.forEach(data, function(val, key) {
fd.append(key, val);
});
var args = {
method: 'POST',
url: url,
data: fd,
headers: {'Content-Type': undefined},
transformRequest: angular.identity
};
return $http(args);
};
return {
readAsDataUrl: readAsDataURL
};
}])

整个上传的过程,点击“重新上传”按钮,file-model指令绑定的change事件会检测本次选择的图片与上次是否为一致,不一致则会执行file-model定义时的代码
element.bind(‘change’, function(event){
scope.$apply(function(){
modelSetter(scope, element[0].files[0]);
});
//附件预览
scope.file = (event.srcElement || event.target).files[0]; //给Controller 中$scope.file赋值
scope.getFile(); //调用Controller 中 $scope.getFile();
this.value = ‘’; //清除已上传的文件,否则无法连续上传相同文件
});
控制器中的$scope.getFile()函数用到fileReader.readAsDataUrl函数上传图片给后台,这个函数在定义fileReader时被定义

定义指令时,若没有清除已上传文件,连续多次上传时,将导致无法连续上传相同图片的bug.