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 相关文章推荐
让GoogleCode的SVN下的HTML文件在FireFox下正常显示.
May 25 Javascript
Jquery中获取iframe的代码
Jan 11 Javascript
Javascript基础教程之JavaScript语法
Jan 18 Javascript
Jquery ajax请求导出Excel表格的实现代码
Jun 08 Javascript
chrome浏览器如何断点调试异步加载的JS
Sep 05 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
Dec 29 Javascript
vue.js 初体验之Chrome 插件开发实录
May 13 Javascript
JS实现经典的中国地区三级联动下拉菜单功能实例【测试可用】
Jun 06 Javascript
elementui的默认样式修改方法
Feb 23 Javascript
vue2 前端搜索实现示例
Feb 26 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
May 16 jQuery
vue 地图可视化 maptalks 篇实例代码详解
May 21 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 杂谈《重构-改善既有代码的设计》之三 重新组织数据
2012/04/09 PHP
简单了解WordPress开发中update_option()函数的用法
2016/01/11 PHP
php实现简单加入购物车功能
2017/03/07 PHP
js字符编码函数区别分析
2008/06/05 Javascript
JavaScript插入动态样式实现代码
2012/02/22 Javascript
基于JQuery的$.ajax方法进行异步请求导致页面闪烁的解决办法
2016/05/10 Javascript
Javascript缓存API
2016/06/14 Javascript
js实现可输入可选择的select下拉框
2016/12/21 Javascript
原生js实现网页顶部自动下拉/收缩广告效果
2017/01/20 Javascript
初探nodeJS
2017/01/24 NodeJs
基于Vue 实现一个中规中矩loading组件
2019/04/03 Javascript
vue+element项目中过滤输入框特殊字符小结
2019/08/07 Javascript
vue.js中ref及$refs的使用方法解析
2019/10/08 Javascript
使用Vue Composition API写出清晰、可扩展的表单实现
2020/06/10 Javascript
Python中正则表达式的用法实例汇总
2014/08/18 Python
Python脚本暴力破解栅栏密码
2015/10/19 Python
Python编程实现二叉树及七种遍历方法详解
2017/06/02 Python
PyCharm在win10的64位系统安装实例
2017/11/26 Python
Python实现Kmeans聚类算法
2020/06/10 Python
python3.5的包存放的具体路径
2020/08/16 Python
CSS3 创建网页动画实现弹跳球动效果
2018/10/30 HTML / CSS
美国存储和组织商店:The Container Store
2017/08/16 全球购物
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
美国在线购买和出售礼品卡网站:EJ Gift Cards
2019/06/09 全球购物
保加利亚运动鞋购物网站:SneakerStudio.bg
2020/12/23 全球购物
C语言开发工程师测试题
2016/12/20 面试题
经济信息管理专业大学生求职信
2013/09/27 职场文书
捐款倡议书范文
2014/02/02 职场文书
高中毕业自我评价
2014/02/08 职场文书
一年级班主任感言
2014/03/08 职场文书
2015年采购员工作总结
2015/04/27 职场文书
教师师德工作总结2015
2015/07/22 职场文书
2016见义勇为事迹材料汇总
2016/03/01 职场文书
Pandas加速代码之避免使用for循环
2021/05/30 Python
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android
修改并编译golang源码的操作步骤
2021/07/25 Golang