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 应用技巧集合[推荐]
Aug 30 Javascript
IE之动态添加DOM节点触发window.resize事件
Jul 27 Javascript
js读取本地excel文档数据的代码
Nov 11 Javascript
JS通过分析userAgent属性来判断浏览器的类型及版本
Mar 28 Javascript
jquery实现九宫格大转盘抽奖
Nov 13 Javascript
微信公众号  提示:Unauthorized API function 问题解决方法
Dec 05 Javascript
在 webpack 中使用 ECharts的实例详解
Feb 05 Javascript
vue指令只能输入正数并且只能输入一个小数点的方法
Jun 08 Javascript
vue项目中跳转到外部链接的实例讲解
Sep 20 Javascript
javascript实现简易数码时钟
Mar 30 Javascript
简单聊聊Vue中的计算属性和属性侦听
Oct 05 Vue.js
js作用域及作用域链工作引擎
Jul 07 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输出全球各个时区列表的方法
2015/03/31 PHP
详谈php ip2long 出现负数的原因及解决方法
2017/04/05 PHP
thinkPHP微信分享接口JSSDK用法实例
2017/07/07 PHP
php反序列化长度变化尾部字符串逃逸(0CTF-2016-piapiapia)
2020/02/15 PHP
你可能不再需要JQUERY
2021/03/09 Javascript
ASP.NET中基于JQUERY的高性能的TreeView补充
2011/02/23 Javascript
THREE.JS入门教程(3)着色器-下
2013/01/24 Javascript
Extjs实现进度条的两种便捷方式
2013/09/26 Javascript
sogou地图API用法实例教程
2014/09/11 Javascript
JQuery实现带排序功能的权限选择实例
2015/05/18 Javascript
javascript控制图片播放的实现代码
2020/07/29 Javascript
javascript中return,return true,return false三者的用法及区别
2015/11/17 Javascript
老生常谈javascript变量的命名规范和注释
2016/09/29 Javascript
微信小程序 中wx.chooseAddress(OBJECT)实例详解
2017/03/31 Javascript
微信小程序基于本地缓存实现点赞功能的方法
2017/12/18 Javascript
js传递数组参数到后台controller的方法
2018/03/29 Javascript
JS Math对象与Math方法实例小结
2019/07/05 Javascript
javascript 高级语法之继承的基本使用方法示例
2019/11/11 Javascript
Postman环境变量全局变量使用方法详解
2020/08/13 Javascript
[06:38]DOTA2怒掀电竞风暴 2013Chinajoy
2013/07/27 DOTA
用virtualenv建立多个Python独立虚拟开发环境
2017/07/06 Python
Python通过matplotlib绘制动画简单实例
2017/12/13 Python
django 开发忘记密码通过邮箱找回功能示例
2018/04/17 Python
Python list列表中删除多个重复元素操作示例
2019/02/27 Python
python 实现在一张图中绘制一个小的子图方法
2019/07/07 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
2020/05/18 Python
使用TensorBoard进行超参数优化的实现
2020/07/06 Python
IE支持HTML5的解决方法
2009/10/20 HTML / CSS
HTML5中的Web Notification桌面通知功能的实现方法
2019/07/29 HTML / CSS
门诊挂号室室长岗位职责
2013/11/27 职场文书
大学生村官任职感言
2014/01/09 职场文书
音乐之声观后感
2015/06/04 职场文书
一封真诚的自荐信帮你赢得机会
2019/05/07 职场文书
Django中的JWT身份验证的实现
2021/05/07 Python
MySQL完整性约束的定义与实例教程
2021/05/30 MySQL
一篇文章带你了解Python和Java的正则表达式对比
2021/09/15 Python