zoukankan      html  css  js  c++  java
  • Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定

    一放假就高产似母猪了。

    00.混乱的前端界

    Angular1.x确实是个学习成本很高的框架,刚开始实习那会儿,前端啥也不懂,工头说用Angular,我们这群小弟也只能硬着头皮学。在这之前,前端的东西大部分都用的jQuery,而Angular正好是和jQuery的思维是相反的,开发过程中遇到了不少坑。而Angular团队也放弃了1.x开始开发和React神似的2.0版本,唉,真是沧海桑田啊。

    01.Angular vs jQuery

    Angular模块化和解耦的思路确实值得一学,但是相对于成熟的jQuery插件库,Angular就显得寒酸了不少,比如,Angular-UI中日期控件是这样的:

    丑的不要不要的,还不能选时间,相比之下jQuery就有很多优秀的控件了比如这样的:

    此插件传送门:http://xdsoft.net/jqplugins/datetimepicker/

    那么问题来了,控件一般是直接像这样$("#xx").val("xx")直接塞值进<input />标签的,这不会触发ng-change事件,ng-model也不会被更新,于是笔者写了个Angular适配指令,来实现这个控件的双向绑定,对于其他jQuery插件,也可以用类似的思路来进行适配。

    10.干货

    下面是一个Demo,比较两者的不同,注意右边ng-bind的属性使用adapter是会同步变化的↓

    Demo传送门:http://ydxxwb.sinaapp.com/angularTimePicker/

    Github地址:https://github.com/Code2Life/angular.DatetimePicker.git

    
    angular.module("directives",[]).directive("datetimepicker",function(){
        return {
            restrict: "EA",   //指令作用范围是element或attribute
            require : "ngModel",  //控制器是指令标签对应的ngModel
            link: function (scope, element, attrs, ctrl) {
    
                var unregister = scope.$watch(function(){               //关键点,下面详述
    
                    $(element).append("<input id='date-"+attrs.dateid+"' style='border:none;100%' value='"+ctrl.$modelValue+"'>"); //template用不好,于是用这个笨办法加上input标签
    
                    element.on('change', function() {  //注册onChange事件,设置viewValue
                        scope.$apply(function() {
                            ctrl.$setViewValue($("#date-"+attrs.dateid).val());
                        });
                    });
    
                    element.on('click',function(){    //click触发日期框
                        $("#date-"+attrs.dateid).datetimepicker({ 
                            format : attrs.format || 'Y/m/d h:i',   //格式
                            onClose : function(){                   //关闭日期框时手动触发change事件
                                element.change();
                            }
                        });
                    });
    
                    element.click();        //第一次绑定事件,模拟一次click,否则肯能要点两下才会出日期框
    
                    return ctrl.$modelValue;
                }, initialize);
    
                function initialize(value){  //下面再说
                    ctrl.$setViewValue(value);
                    unregister();
                }
            }
        }
    });

    写这个指令过程中遇到了一个大坑,查了很久才明白,Angular初始化一个ngModel的时候,是会先给它的value置为NaN,初始化必须要先调用$watch()来监测真正值被设置的时候,然后调用上面的initialize方法来设置view值。否则在Controller中设置的初始值会变成NaN。

    11.不足之处

    原插件是有很多可选项的,我只实现了一个最基本的format,有其他需求的自行改代码吧。可以利用第三个attrs参数获取属性,然后调用原插件的配置方法,来实现更复杂的逻辑。

  • 相关阅读:
    [CSS揭秘]扩大可点击区域
    [CSS揭秘]鼠标光标
    [JavaScript语法学习]全面介绍对象
    [JavaScript语法学习]全面介绍函数
    [JavaScript语法学习]全面介绍Array
    [Linux养成计划]Linux简介
    [Redis]Redis安装和使用
    [Python笔记]Python学习笔记三
    Linux_基础_文件权限
    Git_Eclipse:[8]Git分支操作
  • 原文地址:https://www.cnblogs.com/code2life/p/5097330.html
Copyright © 2011-2022 走看看