遇到个需求需要写dashboard,里面有各种widget,比如图片上传的widget,需要写一个组件来上传图片,上传之后显示上传的图片;传统的方式通过form很容易提交,但是Angularjs稍微有点问题;下面来梳理下整个过程;
首先是widget-image 组件,这个组件的功能是根据传入的参数(图片的路径),如果有就加载图片,如果没有,就显示一个上传按钮,点击按钮弹出文件选择对话框去上传图片;先看下widget-image directive内容;
widget-image.directive.js内容
(function () {
'use strict';
angular
.module('app')
.directive('widgetImage', widgetImage);
function widgetImage(DashboardStorage, Dashboard) {
return {
restrict: 'A',
replace: true,
templateUrl: 'app/entities/dashboard/widget-image.html',
link: function (scope, element, attrs) {
scope.imageSrc = attrs.value;
scope.storagehash = attrs.storagehash;
scope.selectFile = function () {
element.find("input")[0].click();
};
scope.finishUpload = function (src) {
scope.imageSrc = src;
DashboardStorage.setItem(scope.storagehash, scope.imageSrc);
}
}
};
}
})();
widget-image.html
这里点击之后调用selectFile去触发隐藏的input type=“file”的点击事件去弹出对话框;这里的重点是angularjs里面input type="file"无法使用ng-change事件来watch文件选择的操作;所以,添加了个dashboard-image-upload的directive,用来监听文件上传,上传完成之后会调用这里的finishUpload方法回调;
(function () {
'use strict';
angular
.module('App')
.directive('dashboardImageUpload', dashboardImageUpload);
function dashboardImageUpload(Dashboard, ngNotify) {
return {
scope: {
fileName: "=storageHash",
finishUpload: "&"
},
link: function (scope, element, attributes) {
element.bind("change", function (changeEvent) {
scope.$apply(function () {
var file = changeEvent.target.files[0];
Dashboard.uploadDashboardImage(file, scope.fileName).then(function (result) {
scope.finishUpload({src: result.data});
}, function () {
ngNotify.set("图片上传失败!", 'error');
});
});
});
}
}
}
})();
这里我传入了一个参数storageHash,这个参数是业务里面的需要,标识我要生成的图片的名称;通过change事件来触发上传的操作;文件的内容会保存在changeEvent.target.files[0]里面;然后调用图片上传服务,提交图片并返回上传成功的图片src;
function uploadDashboardImage(file, name) {
return $http({
method: 'POST',
url: 'api/dashboard-images/upload',
headers: {
'Content-Type': undefined
},
data: {
file: file,
name: name
},
transformRequest: function (data, headersGetter) {
var formData = new FormData();
angular.forEach(data, function (value, key) {
formData.append(key, value);
});
var headers = headersGetter();
delete headers['Content-Type'];
return formData;
},
transformResponse: function (data) {
return data;
}
})
}
这里一定要指定'Content-Type': undefined,否则后端接受不到file的内容;
这里直接用RequestParam来接受就可以了
@RequestMapping(value = "/dashboard-images/upload", method = RequestMethod.POST)
public ResponseEntity upload(@RequestParam("file") MultipartFile file,@RequestParam String name) {
String src = imageService.uploadDashboardImage(file, name);
return new ResponseEntity<>(src, HttpStatus.OK);
}