AngularJS+Bootstrap实现多文件上传与管理


Posted in Javascript onNovember 08, 2016

最近一个项目中需要实现多文件上传与管理,而项目是基于bootstrap开发的,所以查了一些bootstrap文件上传插件,最后发现还是bootstrap-fileinput最美观,该插件可以实现多文件的上传与管理(插件官方地址:http://plugins.krajee.com/file-input),具体的效果如下:

 AngularJS+Bootstrap实现多文件上传与管理

(bootstrap-fileinput不局限于图片上传,也可以实现文件上传,但图片的缩略图容易辨识,这里就以图片上传为例)

 该插件基本的操作可以参考:JS文件上传神器bootstrap fileinput详解,本文主要针对多文件管理。 

在讲该插件如何使用前,先跟大家讲一下项目中关于图片管理的需求:

1、可以上传多个图片

2、只有当点击保存按钮时,图片信息才保存至数据库

3、可以加载已经保存到数据库的图片信息,并提供删除功能 

因此,我们可以规定几个文件状态:

已选择:已经放入到插件中,但还没有上传到服务器。如上图中第3个图片,该图片下方有上传按钮。

已上传:已经上传到服务器,但图片信息没有保存到数据库。如上图中第2个图片,该图片下方有100%的进度条。

已保存:图片信息已经保存至数据库的图片,如上图中第1张图,这些图片下方有删除按钮,点击删除时会将图片信息从数据库中删除。 

一、引入必要文件

<link href="<%=path%>/static/css/bootstrap-3.3.5/bootstrap.min.css" rel="stylesheet">
<link href="<%=path%>/static/css/bootstrap-3.3.5/fileinput.css" rel="stylesheet">

<script src="<%=path%>/static/js/jquery-1.11.3.js"></script>
<script src="<%=path%>/static/js/angularjs-1.3.9/angular.min.js"></script>
<script src="<%=path%>/static/js/bootstrap-3.3.5/bootstrap.min.js"></script>
<script src="<%=path%>/static/js/bootstrap-3.3.5/fileinput.js"></script>
<script src="<%=path%>/static/js/bootstrap-3.3.5/fileinput_locale_zh.js"></script>
 

其中fileinput.js和fileinput_locale_zh.js都在插件待官方包中,angular.min.js和bootstrap.min.js就不多介绍了

二、多文件上传

首先在页面中定义file控件:

<input id="input-images" type="file" multiple class="file-loading" accept="image/*">

然后对该控件进行初始化,就可以实现该组件的多文件上传了:

$("#input-images").fileinput({
  uploadUrl: "<%=path%>" + "/album/pictureFileUpload",
  allowedFileExtensions: ["jpg", "png", "gif"],
  resizePreference: 'height',
  maxFileCount: 10,
  language: 'zh',
  overwriteInitial: false,
  resizeImage: true,
  });

当然,初始化时的属性有很多,这里不一一介绍了,后台代码(使用JFinal)如下:

public void pictureFileUpload() {
 UploadFile uploadFile = getFile();
 renderJson("{\"link\":" + "\"/fileinput/upload/" + uploadFile.getFileName()
 + "\"" + ",\"fileName\":\"" + uploadFile.getOriginalFileName()
 + "\"}");
 }

注意最后一定要返回Json,哪怕返回一个空json串(“{}”),返回的值保存在前台的data.response中。

三、已有文件的加载与删除

已有文件的加载是指将服务器上已经存在的文件展示在该控件中,以实现文件管理,提供删除功能,这主要依赖于initialPreview实现的。

将服务器上的文件名称和文件地址获取之后,使用initialPreview和initialPreviewConfig完成加载和定义删除操作:

var initPreview = new Array();//展示元素
 var initPreviewConfig = new Array();//展示设置
 
 $.post(
 "<%=path%>" + "/album/getPicsByAlbum", 
 {albumId : albumId}, 
 function(result) {
 for(var i=0;i<result.length;i++){
 var pictureFile = result[i];
 //用于展示已经上传的图片
  initPreview.push("<img src='" + pictureFile.PICADDRESS 
   + "' class='file-preview-image' alt='"+pictureFile.PICNAME+"' title='"+pictureFile.PICNAME+"'>");
  var config = new Object();
  config.caption = pictureFile.PICNAME;
  config.url="<%=path%>" + "/album/deletePicById";
  config.key=pictureFile.ID;
  initPreviewConfig.push(config);
 }
 initFileInput($scope);
  $("#input-images").fileinput('refresh', {
  initialPreview: initPreview,
  initialPreviewConfig: initPreviewConfig
  });
 }
 );

点击删除图标,会默认把config中待key值传至后台,后台中定义deletePicById方法即可:

public void deletePicById() {
 String picId = getPara("key");
 service.deletePicById(Integer.valueOf(picId));
 renderJson("{}");
 }

四、几点疑问的解答

1、为什么model里没有属性,却可以在前端展示相关属性?
这里主要使用了JFinal的ActiveRecord功能,无需定义属性和setter,getter方法,属性值被映射在model里的attrs里,这个属性是<key, value>的键值对,而key值就是数据库的字段名。 特别提醒:虽然SQL语句不分区大小写,但字段名还是存在大小写的,如果字段名是大写的,那么映射到model里的key就是大写的,同时JFinal的默认id为主键的策略也不能生效,需要在 configPlugin中设置,如下:arp.addMapping("pictures", "ID", Picture.class),建议大家按照Java命名规范命名数据库字段。

2、(参考代码)中初始化FileInput为什么要执行clear,destory操作?

因为FileInput插件在选择文件后,不管有没有上传,都会保留文件在file域中,因此再点击时会显示上一次选择的文件,不符合多相册管理的需求,原本以为clear操作就可以清空file域(官方文档这么说的),但实际操作发现并没有清空,因此才调用clear,destory后再重新初始化文件上传控件。(这一点不太确定,希望有大神可以指点)

3、保存时怎么知道那些图片需要存数据库,这是基于什么实现的?

$scope上有个selectedPics数组,该属性负责保存最终那些文件会保存到数据库。在文件选择后会将选择待文件信息保存到这个数组中,但hasUpload属性为false;在文件上传后,会修改对应的hasUpload为true;在上传成功后执行删除(还没有保存到数据库)会从数组中移除对应的元素。有人会问,那选择文件后不上传直接删除,那文件信息岂不是会占用数据位置从而导致元素错乱吗?其实并不会,在fileuploaded事件中,哪些图片已经hasUpload,是直接改数组对应位置元素的值的,而数组坐标是通过图片所在DIV的data-fileindex属性值获得的, 该值会一直增加,不会替补空缺值,不会因为删除图片而变动,正好与selectedPics数组相对应。
var idx = $("#"+previewId).attr("data-fileindex");
例如我选择了3张图片,此时没有上传,他们依次的data-fileindex为0,1,2,当我删除中间那个图片并重新选择新图片时,那么他们的data-fileindex就会变为0,2,3。

五、代码参考
最后本人才学AngularJS,代码写的不够纯熟,如有不妥之处,欢迎大家留言,示例代码在文章末尾,数据库脚本为files.sql(MySQL),大家多看看代码吧。

源码下载:http://xiazai.3water.com/201611/yuanma/BSfileinput(3water.com).rar

如果大家还想深入学习,可以点击这里进行学习,再为大家附两个精彩的专题:Bootstrap学习教程 Bootstrap实战教程

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
基于jQuery的消息提示插件 DivAlert之旅(二)
Apr 01 Javascript
jquery下实现overlay遮罩层代码
Aug 25 Javascript
jquery动画1.加载指示器
Aug 24 Javascript
JQuery对id中含有特殊字符的转义处理示例
Sep 06 Javascript
一个Action如何调用两个不同的方法
May 22 Javascript
js使用removeChild方法动态删除div元素
Aug 01 Javascript
jsMind通过鼠标拖拽的方式调整节点位置
Apr 13 Javascript
详谈for循环里面的break和continue语句
Jul 20 Javascript
微信小程序实现文件、图片上传功能
Aug 18 Javascript
layui 数据表格 点击分页按钮 监听事件的实例
Sep 02 Javascript
如何在Vue.JS中使用图标组件
Aug 04 Javascript
关于uniApp editor微信滑动问题
Jan 15 Javascript
AngularJS压缩JS技巧分析
Nov 08 #Javascript
jQuery的Read()方法代替原生JS详解
Nov 08 #Javascript
bootstrap fileinput完整实例分享
Nov 08 #Javascript
AngularJS动态加载模块和依赖的方法分析
Nov 08 #Javascript
JS文件上传神器bootstrap fileinput详解
Jan 28 #Javascript
Javascript数组循环遍历之forEach详解
Nov 07 #Javascript
关于webuploader插件使用过程遇到的小问题
Nov 07 #Javascript
You might like
PHP函数学习之PHP函数点评
2012/07/05 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(七)
2014/06/23 PHP
54个提高PHP程序运行效率的方法
2015/07/19 PHP
php实现json编码的方法
2015/07/30 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
2015/12/22 PHP
php微信公众号开发之现金红包
2018/04/16 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
javascript 打印页面代码
2009/03/24 Javascript
跨域请求之jQuery的ajax jsonp的使用解惑
2011/10/09 Javascript
jquery实现漂浮在网页右侧的qq在线客服插件示例
2013/05/13 Javascript
javascript实现树形菜单的方法
2015/07/17 Javascript
iframe跨域通信封装详解
2015/08/11 Javascript
Javascript打印局部页面实例
2016/06/21 Javascript
微信小程序 教程之数据绑定
2016/10/18 Javascript
基于LayUI实现前端分页功能的方法
2017/07/22 Javascript
Angularjs 事件指令详细整理
2017/07/27 Javascript
JQuery用$.ajax或$.getJSON跨域获取JSON数据的实现代码
2017/09/23 jQuery
浅谈vux之x-input使用以及源码解读
2018/11/04 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
使用RxJS更优雅地进行定时请求详析
2019/06/02 Javascript
vue 内联样式style中的background用法说明
2020/08/05 Javascript
Python中使用select模块实现非阻塞的IO
2015/02/03 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
python变量赋值方法(可变与不可变)
2019/01/12 Python
Python获取基金网站网页内容、使用BeautifulSoup库分析html操作示例
2019/06/04 Python
python实现宿舍管理系统
2019/11/22 Python
Jupyter Notebook远程登录及密码设置操作
2020/04/10 Python
Python实现LR1文法的完整实例代码
2020/10/25 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
P D PAOLA意大利官网:西班牙著名的珠宝首饰品牌
2019/09/24 全球购物
几道PHP面试题
2013/04/14 面试题
学习经验交流会主持词
2014/04/01 职场文书
高二学年自我鉴定范文(2篇)
2014/09/26 职场文书
2014办公室年度工作总结
2014/12/09 职场文书
2015年试用期工作总结
2014/12/12 职场文书
一篇文章告诉你如何实现Vue前端分页和后端分页
2022/02/18 Vue.js