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实现的距离现在多长时间后的一个格式化的日期
Oct 29 Javascript
jquery中实现简单的tabs插件功能的代码
Mar 02 Javascript
js关闭子窗体刷新父窗体实现方法
Dec 04 Javascript
javascript自适应宽度的瀑布流实现思路
Feb 20 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
Sep 02 Javascript
JavaScript中实现无缝滚动、分享到侧边栏实例代码
Apr 06 Javascript
jQuery滚动新闻实现代码
Jun 26 Javascript
seajs学习教程之基础篇
Oct 20 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
Mar 30 Javascript
JS简单实现自定义右键菜单实例
May 31 Javascript
vue-router路由与页面间导航实例解析
Nov 07 Javascript
微信小程序基础教程之echart的使用
Jun 01 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中对xml读取的相关函数的介绍一
2008/06/05 PHP
php通过array_push()函数添加多个变量到数组末尾的方法
2015/03/18 PHP
php递归函数三种实现方法及如何实现数字累加
2015/08/07 PHP
简单谈谈PHP中的Reload操作
2016/12/12 PHP
用js实现的页面关键字密度查询代码
2007/12/27 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
vueJS简单的点击显示与隐藏的效果【实现代码】
2016/05/03 Javascript
js中最容易被忽视的事件问题大总结
2016/05/15 Javascript
浅谈Javascript数组(推荐)
2016/05/17 Javascript
浅谈JavaScript 覆盖原型以及更改原型
2016/08/31 Javascript
iOS + node.js使用Socket.IO框架进行实时通信示例
2017/04/14 Javascript
使用travis-ci如何持续部署node.js应用详解
2017/07/30 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
2018/04/08 Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
2018/12/03 Javascript
详解基于mpvue微信小程序下载远程图片到本地解决思路
2019/05/16 Javascript
Vue.js中的高级面试题及答案
2020/01/13 Javascript
js瀑布流布局的实现
2020/06/28 Javascript
JavaScript arguments.callee作用及替换方案详解
2020/09/02 Javascript
逐行分析鸿蒙系统的 JavaScript 框架(推荐)
2020/09/17 Javascript
[02:57]2014DOTA2国际邀请赛 选手辛苦解说更辛苦
2014/07/10 DOTA
Python 两个列表的差集、并集和交集实现代码
2016/09/21 Python
Python走楼梯问题解决方法示例
2018/07/25 Python
在Python中过滤Windows文件名中的非法字符方法
2019/06/10 Python
Python中的pathlib.Path为什么不继承str详解
2019/06/23 Python
python 实现矩阵填充0的例子
2019/11/29 Python
TensorFlow 读取CSV数据的实例
2020/02/05 Python
Win10环境中如何实现python2和python3并存
2020/07/20 Python
Linux安装Python3如何和系统自带的Python2并存
2020/07/23 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
canvas粒子动画背景的实现示例
2018/09/03 HTML / CSS
函授自我鉴定
2013/11/06 职场文书
秘书行业自我鉴定范文
2013/12/30 职场文书
《地震中的父与子》教学反思
2014/04/10 职场文书
党员干部学习心得体会
2016/01/23 职场文书
解除租赁合同协议书
2016/03/21 职场文书
关于企业的执行力标语大全
2020/01/06 职场文书