zoukankan      html  css  js  c++  java
  • angular上传获取图片的directive指令

    在AngularJS中,操作DOM一般在指令中完成,那么指令是如何实现的呢?
    指令的作用是把我们自定义的语义化标签替换成浏览器能够认识的HTML标签

    一般的事件监听是在对静态的dom绑定事件,而如果在指令中动态生成了DOM节点,动态生成的节点不会被JS事件监听。这也是使用directive指令来处理的原因。

    解决问题的开始先介绍下directive的几个属性

    1.restrict
    主要是定义directive自定义指令的方式,一般有以下几种
    E: 表示该directive仅能以element方式使用,即:<my-dialog></my-dialog>
    A: 表示该directive仅能以attribute方式使用
    EA: 表示该directive

    2.scope
    写上该属性时,就表示这个directive不会从它的controller里继承$scope对象,而是会重新创建一个

    3.link
    link包含了三个属性分别是scope,element,attrs
    scope就相当于上文提到scope,其实是一样的
    element就相当于jquery的获取对象如$('my-dialog')
    attra则是个类型map的数据类型,包括你加入指令那句html代码的所有属性。

    <input type="file" id="photo_back" name="id_photo_back"
     ng-model="kycpeople.id_photo_back" custom-on-change="uploadFile"/>
    
    .directive('customOnChange',function(){
        return {
            restrict:'A',
            link:function(scope,element,attrs){
                var onChangeHandler = scope.$eval(attrs.customOnChange);
                element.bind('change',onChangeHandler);
            }
        };
        });
    

      如上所示,自定义一个custom-on-change的指令,restrict:'A'表明该指令是一个attribute,给指令添加一个名字作为之后事件绑定触发的函数,当directive被渲染后,input就被绑定了一个change事件,当元素的值被修改时,标签input的customOnChange指令值uploadFile触发事件
    如下

    $scope.uploadFile = function (event) {
            var file = event.target.files[0];
            $scope.file = file;
        };
    

      

    以上代码解决了angular图片上传过程图片获取的问题。

    那么假设此时要实现多个图片上传且实时预览,这时候要怎么实现呢?

    首先,先把业务处理封装成service,如下

    angular.module('app').service('foo', function ($translate) {
    
        this.getPrivate = function (tmp) { .  // 获取文件对象
            var file = event.target.files[0];
            return file;
        };
        this.getimgname = function (tmp) {  // 获取图片名称
            var filename = event.target.files[0].name;
            return filename;
        };
        this.getimgurl = function (filename,callback) { // 获取图片并预览
            if(filename==null)
            {
                return;
            }
            var tmp = new FileReader();
            tmp.onload = function (ev) { //调用回调函数
                callback(ev.target.result);
            };
            tmp.readAsDataURL(filename);
        };
    
    });
    

      接下来是在创建的控制器里面加入service的依赖,并使用这个service中的函数

    angular.module('app').controller('kycForPersoncontroller', function (foo,$scope,$http) {
     $scope.uploadFile = function (event) {
            $scope.file = foo.getPrivate(event);
            $scope.uploadimg=foo.getimgname(event);
            foo.getimgurl($scope.file,function (result) {
                    $scope.img = result;
                    console.log($scope.img);
            });
        };
    

      到这里我遇到一个问题阻塞我的思路,就是进入service的getimgurl函数时里面有一个我自己的定义的回调函数callback(ev.target.result),添加图片后这个回调函数返回的result值即是上传图片成功后的base64值,用控制台能够打印出来,但是视图却没显示出来,这是为什么?

     <img src={{imgback}}></img>
    

      

    数据绑定好了,图片怎么显示不出来,angular所谓的双向绑定不是有任何数据发生了变化,view会跟着改变,scope模型会自动地更新吗?

    这是因为回调函数中,angular并不知道你修改了什么。就像你使用setTimeout()来更新一个scope model,它并不知道你更新什么。这种情况下,调用$apply()就是你的责任了(如上),它会自动触发$rootScope.$digest(),从而让watchers被触发用以更新view,才能做到手动更新model,view视图也会随之显示。

    正确的写法

     $scope.uploadFile = function (event) {
            $scope.file = foo.getPrivate(event);
            $scope.uploadimg=foo.getimgname(event);
            foo.getimgurl($scope.file,function (result) {
                 $scope.$apply(function () {
                    $scope.img = result;
                });
            });
        };
    

      最后做下总结,AngularJS是否能检测到你对于model的修改。如果它不能检测到,那么你就需要手动地调用$apply()。

    文章记录自:

    http://www.jianshu.com/p/0d3652a5db21

  • 相关阅读:
    程序员如何跨过自我推销的难关?
    常用接口分类与模块设计的方法
    如何设计分层架构和交互接口 API ?
    如何建立架构师的立体化思维?
    从程序员到架构师的技能图谱
    selenium鼠标、键盘操作常用API
    selenium元素定位之-css定位
    python每日一练之集合set
    selenium2简单的定位方法和Xpath定位
    python之元组
  • 原文地址:https://www.cnblogs.com/qiyecao/p/6908997.html
Copyright © 2011-2022 走看看