Angularjs实现多图片上传预览功能


Posted in Javascript onJuly 18, 2018

最近要实现一个多图片上传的预览功能,网上有很多例子大多不太完整,我就把他们的整合了下并且加了一些功能和界面,我们只需要调用一条指令就可以实现,但传给后台还需要额外的代码,会在后面controller里介绍。不知道封装的是否符合标准,还希望大家一起讨论下,如果有时间封装下Angular4的图片上传和预览分享给大家。

图片上传的预览,我们最主要解决的是拿到input的on-change事件,再是读取图片,读取图片我们需要用到FileReader。

我们先写一个读取图片的服务,这是网上的一位大佬写的,我就直接拿了过来

/**
 * 图片上传获取返回的url
 */
      app .factory('fileReader', ["$q", "$log", function($q, $log){
        var onLoad = function(reader, deferred, scope) {
          return function () {
            scope.$apply(function () {
              deferred.resolve(reader.result);
            });
          };
        };

        var onError = function (reader, deferred, scope) {
          return function () {
            scope.$apply(function () {
              deferred.reject(reader.result);
            });
          };
        };

        var getReader = function(deferred, scope) {
          var reader = new FileReader(); //fileReader
          reader.onload = onLoad(reader, deferred, scope);
          reader.onerror = onError(reader, deferred, scope);
          return reader;
        };

        var readAsDataURL = function (file, scope) {
          var deferred = $q.defer();
          var reader = getReader(deferred, scope);   
          reader.readAsDataURL(file);  
          return deferred.promise;

        };

        return {
          readAsDataUrl: readAsDataURL 
      };
}])

我们现在有了图片的读取,我们再来搞定图片的on-change事件

/**
 * 图片上传预览
 */
app .directive('file', ['$parse', 'fileReader', function ($parse, fileReader) { 
      return {
        restrict: 'A',
        link: function(scope, element, attrs, ngModel) {

          var model = $parse(attrs.file);
          var modelSetter = model.assign;
          console.log(modelSetter)
          element.bind('change', function(event){
            scope.$apply(function(){
              modelSetter(scope, element[0].files[0]);
            });
            //附件预览         
               scope.imgupload = (event.srcElement || event.target).files[0];
               getFile(scope.imgupload, scope);

              //获得预览图地址并且把file对象放入上传合集内
               function getFile (imgupload, scope) {
                 if(!imgupload) {
                   return;
                 }
                 fileReader.readAsDataUrl(imgupload, scope)
                        .then(function(result) {
                         scope.imgshows.push(result)
                         var file = document.querySelector('input[type=file]').files[0];
                         scope.uploadimgs.push(file)//这里是放着传给后台的数据file,下面controller的时候会有
                        });
               };
          });
        }
      };
    }])

这里就是提供上传图片预览的样式,还有预览图删除的功能

app .directive('uploadimg', function () { 
      return {
        restrict: 'E', 
        scope: {
          uploadimgs: "="
        },
        templateUrl: './js/directives/uploadimg/uploadimg.html',      
        link: function(scope, element, attrs) {
            scope.imgshows = []//预览图片合集放的是src    
            scope.uploadimg_del = function(index,imgs) {  
                scope.imgshows.splice(index,1);
                scope.uploadimgs.splice(index,1);
      }
     }
 }
})
<style type="text/css">
.fileupload {
  width: 100px;
  height: 100px;
  border: 1px dotted #ccc;
  display: inline-block;
}
.fileupload-icon {
  font-size:32px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%,-50%);
}
</style>
<div>
  <div class="fileupload pos-rlt" ng-repeat="imageSrc in imgshows">
    <img ng-src="{{imageSrc}}" style="max-width:200px;max-height:300px;margin:0 auto; display:block;" class="pos-rlt" width=100%; height=100%;/>
    <i class="icon ion-close-circled" style="position: absolute; top:5px; right: 5px" ng-click="uploadimg_del($index, imgshows)"></i>
  </div>
  <div class="fileupload pos-rlt clear" >
    <i class="icon ion-plus-round fileupload-icon"></i>
    <input type="file" style="display:inline-block; width: 100%; height: 100%; opacity:0" name="upload_img" file="upload_img" placeholder="选择图片" accept="image/png,image/gif,image/jpeg,image/jpg"  >
  </div>
</div>
</label>

最后的调用也很简单
我们只需要在2个地方加代码一个是在界面,一个是在Controller里

<uploadimg uploadimgs="uploadimgs"></uploadimg>

这个是在Controller里的,这是用来传给后台的数据集合,我们需要传给后台的是file对象

$scope.uploadimgs = []//上传图片合集放的是file对象

如何传给后台呢,直接附上代码,其实不难

$scope.save = function() {     
    var Fromdata = {
      'name': $scope.form.name,
      'desc': $scope.form.descr,
      'price': $scope.form.price,
      'status': $scope.form.status?1:0,

    }
    var uploadData = createFromData(Fromdata)
    for(var i = 0; i < $scope.uploadimgs.length; i++) {
      uploadData.append('upload_imgs', $scope.uploadimgs[i])
    }

     $http({
     method:'POST',
     url:"后台地址",
     data: fd,
     headers: {'Content-Type':undefined},
     transformRequest: angular.identity
     })
     .success( function(response){
     //上传成功的操作

     });

   }  

//构造FormData
//@param 是一个对象
function createFromData(Fromdata) {
   var fd = new FormData();
   for(key in Fromdata) {
     fd.append(key,Fromdata[key]); 
   }
   return fd
}

最后给大家看下预览图

Angularjs实现多图片上传预览功能

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

Javascript 相关文章推荐
js的.innerHTML = &quot;&quot;IE9下显示有错误的解决方法
Sep 16 Javascript
设置checkbox为只读(readOnly)的两种方式
Oct 11 Javascript
javascript实现简单的贪吃蛇游戏
Mar 31 Javascript
javascript制作游戏开发碰撞检测的封装代码
Mar 31 Javascript
JQuery实现动态添加删除评论的方法
May 18 Javascript
JavaScript实现垂直向上无缝滚动特效代码
Nov 23 Javascript
JS中的多态实例详解
Oct 15 Javascript
在react中使用vuex的示例代码
Jul 30 Javascript
微信小程序之多列表的显示和隐藏功能【附源码】
Aug 06 Javascript
关于在vue 中使用百度ueEditor编辑器的方法实例代码
Sep 14 Javascript
jquery的$().each和$.each的区别
Jan 18 jQuery
Vue页面切换和a链接的本质区别详解
Nov 12 Javascript
JavaScript实现正则去除a标签并保留内容的方法【测试可用】
Jul 18 #Javascript
微信小程序scroll-x失效的完美解决方法
Jul 18 #Javascript
详解easyui基于 layui.laydate日期扩展组件
Jul 18 #Javascript
Vue无限滑动周选择日期的组件的示例代码
Jul 18 #Javascript
微信小程序修改swiper默认指示器样式的实例代码
Jul 18 #Javascript
webpack4.x打包过程详解
Jul 18 #Javascript
vue系列之requireJs中引入vue-router的方法
Jul 18 #Javascript
You might like
解决163/sohu/sina不能够收到PHP MAIL函数发出邮件的问题
2009/03/13 PHP
PHP制作万年历
2015/01/07 PHP
php时间函数用法分析
2016/05/28 PHP
PHP入门教程之表单与验证实例详解
2016/09/11 PHP
Yii2中SqlDataProvider用法示例
2016/09/22 PHP
PHP实现表单提交时去除斜杠的方法
2016/12/26 PHP
php探针使用原理和技巧讲解
2019/09/17 PHP
ThinkPHP5.1的权限控制怎么写?分享一个AUTH权限控制
2021/03/09 PHP
jquery下拉select控件操作方法分享(jquery操作select)
2014/03/25 Javascript
jquery模拟进度条实现方法
2015/08/03 Javascript
JavaScript实战(原生range和自定义特效)简单实例
2016/08/21 Javascript
JS轮播图中缓动函数的封装
2020/11/25 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
2017/07/03 Javascript
jQuery事件_动力节点Java学院整理
2017/07/05 jQuery
Nodejs之http的表单提交
2017/07/07 NodeJs
mint-ui的search组件在键盘显示搜索按钮的实现方法
2017/10/27 Javascript
基于vue-resource jsonp跨域问题的解决方法
2018/02/03 Javascript
vue proxy 的优势与使用场景实现
2020/06/15 Javascript
浅谈vue中$bus的使用和涉及到的问题
2020/07/28 Javascript
python中文分词,使用结巴分词对python进行分词(实例讲解)
2017/11/14 Python
Python获取航线信息并且制作成图的讲解
2019/01/03 Python
详解python的四种内置数据结构
2019/03/19 Python
如何使用pyinstaller打包32位的exe程序
2019/05/26 Python
10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
2019/08/12 Python
python如何实现不用装饰器实现登陆器小程序
2019/12/14 Python
Python多线程正确用法实例解析
2020/05/30 Python
HTML5新增的标签和属性归纳总结
2018/05/02 HTML / CSS
资生堂英国官网:Shiseido英国
2020/12/30 全球购物
应届生的求职推荐信范文
2013/11/30 职场文书
体育教育专业自荐信范文
2013/12/20 职场文书
2014年教师批评与自我批评思想汇报
2014/09/20 职场文书
2015年学校体育工作总结
2015/04/22 职场文书
追悼会家属答谢词
2015/09/29 职场文书
MySQL获取所有分类的前N条记录
2021/05/07 MySQL
Android在Sqlite3中的应用及多线程使用数据库的建议
2022/04/24 Java/Android
Java Redisson多策略注解限流
2022/09/23 Java/Android