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 相关文章推荐
javascript onmouseout 解决办法
Jul 17 Javascript
简约JS日历控件 实例代码
Jul 12 Javascript
手机平板等移动端适配跳转URL的js代码
Jan 25 Javascript
jQuery 获取/设置/删除DOM元素的属性以a元素为例
May 23 Javascript
JavaScript中的this,call,apply使用及区别详解
Jan 29 Javascript
微信小程序 MD5的方法详解及实例代码
Mar 10 Javascript
Angular限制input框输入金额(是小数的话只保留两位小数点)
Jul 13 Javascript
Javascript实现时间倒计时效果
Jul 15 Javascript
浅谈监听单选框radio改变事件(和layui中单选按钮改变事件)
Sep 10 Javascript
Element Card 卡片的具体使用
Jul 26 Javascript
详解ES6 扩展运算符的使用与注意事项
Nov 12 Javascript
微信小程序实现加入购物车滑动轨迹
Nov 18 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服务端图片生成缩略图的方法详解
2013/06/20 PHP
PHP导入导出Excel代码
2015/07/07 PHP
laravel-admin表单提交隐藏一些数据,回调时获取数据的方法
2019/10/08 PHP
PHP7 标准库修改
2021/03/09 PHP
div+css布局的图片连续滚动js实现代码
2010/05/04 Javascript
javascript使用正则控制input输入框允许输入的值方法大全
2014/06/19 Javascript
基于jQuery实现表单提交验证
2014/11/24 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
JavaScript模拟数组合并concat
2016/03/06 Javascript
jQuery.deferred对象使用详解
2016/03/18 Javascript
js事件驱动机制 浏览器兼容处理方法
2016/07/23 Javascript
JS正则表达式验证账号、手机号、电话和邮箱是否合法
2017/03/08 Javascript
jQuery菜单实例(全选,反选,取消)
2017/08/28 jQuery
基于ES6作用域和解构赋值详解
2017/11/03 Javascript
vue实例中data使用return包裹的方法
2018/08/27 Javascript
微信小程序实现星级评价
2019/11/20 Javascript
Vue微信公众号网页分享的示例代码
2020/05/28 Javascript
基于原生js实现九宫格算法代码实例
2020/07/03 Javascript
vue setInterval 定时器失效的解决方式
2020/07/30 Javascript
Python 实现在文件中的每一行添加一个逗号
2018/04/29 Python
对python抓取需要登录网站数据的方法详解
2018/05/21 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
2018/07/27 Python
python hook监听事件详解
2018/10/25 Python
Python检查ping终端的方法
2019/01/26 Python
python3 property装饰器实现原理与用法示例
2019/05/15 Python
Python的互斥锁与信号量详解
2019/09/12 Python
Pytorch使用MNIST数据集实现CGAN和生成指定的数字方式
2020/01/10 Python
W Hamond官网:始于1979年的钻石专家
2020/07/20 全球购物
临床医学专业毕业生的自我评价
2013/10/17 职场文书
给医务人员表扬信
2014/01/12 职场文书
运动会邀请函范文
2014/02/06 职场文书
装饰工程师岗位职责
2014/06/08 职场文书
实验室标语
2014/06/21 职场文书
故宫的导游词
2015/01/31 职场文书
社会主义核心价值观主题教育活动总结
2015/05/07 职场文书
Python加密与解密模块hashlib与hmac
2022/06/05 Python