zoukankan      html  css  js  c++  java
  • 【经验】Angularjs 中使用 layDate 日期控件

    layDate 控件地址:http://laydate.layui.com/

    前情:原来系统中使用的日期控件是UI bootstrap(地址:https://angular-ui.github.io/bootstrap/)里的。后来因为各种原因,要换掉UI bootstrap中的日期控件,改用layDate日期控件。

    解决思路:将layDate的初始化及相关代码定义在指令里。

    问题关键点:layDate操作的是Html元素的,怎么实现双向绑定,同步Angularjs模板值和Html的元素值。

    指令具体代码:

     1     /**
     2          * 使用示例
     3          * <input def-laydate type="text" id="id1" ng-model="startTime"/>
     4          */
     5         app
     6         .directive('defLaydate', function() {
     7             return {
     8                 require: '?ngModel',
     9                 restrict: 'A',
    10                 scope: {
    11                     ngModel: '='
    14                 },
    15                 link: function(scope, element, attr, ngModel) {
    16                     var _date = null,_config={};
    17                     
    18                         // 初始化参数 
    19                     _config = {
    20                         elem: '#' + attr.id,
    21                         format: attr.format != undefined && attr.format != '' ? attr.format : 'YYYY-MM-DD',
    22                         max:attr.hasOwnProperty('maxDate')?attr.maxDate:'',
    23                         min:attr.hasOwnProperty('minDate')?attr.minDate:'',
    24                         choose: function(data) {
    25                             scope.$apply(setViewValue);
    26                             
    27                         },
    28                         clear:function(){
    29                            ngModel.$setViewValue(null);
    30                         }
    31                     };
    32                     // 初始化
    33                     _date= laydate(_config);
    34 
    35                   
    36                    
    37                     // 模型值同步到视图上
    38                     ngModel.$render = function() {
    39                         element.val(ngModel.$viewValue || '');
    40                     };
    41 
    42                     // 监听元素上的事件
    43                     element.on('blur keyup change', function() {
    44                         scope.$apply(setViewValue);
    45                     });
    46 
    47                     setViewValue();
    48 
    49                     // 更新模型上的视图值
    50                     function setViewValue() {
    51                         var val = element.val();
    52                         ngModel.$setViewValue(val);
    53                     }
    54                 }  
    55             }
    56         })

    ---以上代码使用示例为 <input def-laydate type="text" id="id1" ng-model="startTime"/> 

    注意:1.指令只能用做元素属性。2.元素必须要有唯一id属性。

    到此为止,在Angularjs里使用laydate的基本目标实现了。但是,日期组件难免会有日期选择范围限制的要求,比如日期可选的最大值,最小值。现对指令做优化以满足要求:

     1 app
     2         .directive('defLaydate', function() {
     3             return {
     4                 require: '?ngModel',
     5                 restrict: 'A',
     6                 scope: {
     7                     ngModel: '=',
     8                     maxDate:'@',
     9                     minDate:'@'
    10                 },
    11                 link: function(scope, element, attr, ngModel) {
    12                     var _date = null,_config={};
    13                     
    14                         // 初始化参数 
    15                     _config = {
    16                         elem: '#' + attr.id,
    17                         format: attr.format != undefined && attr.format != '' ? attr.format : 'YYYY-MM-DD',
    18                         max:attr.hasOwnProperty('maxDate')?attr.maxDate:'',
    19                         min:attr.hasOwnProperty('minDate')?attr.minDate:'',
    20                         choose: function(data) {
    21                             scope.$apply(setViewValue);
    22                             
    23                         },
    24                         clear:function(){
    25                            ngModel.$setViewValue(null);
    26                         }
    27                     };
    28                     // 初始化
    29                     _date= laydate(_config);
    30                     
    31                     // 监听日期最大值
    32                     if(attr.hasOwnProperty('maxDate')){
    33                         attr.$observe('maxDate', function (val) {
    34                             _config.max = val;
    35                         })
    36                     }
    37                     // 监听日期最小值
    38                     if(attr.hasOwnProperty('minDate')){
    39                        attr.$observe('minDate', function (val) {
    40                             _config.min = val;
    41                         })
    42                     }
    43                    
    44                     // 模型值同步到视图上
    45                     ngModel.$render = function() {
    46                         element.val(ngModel.$viewValue || '');
    47                     };
    48 
    49                     // 监听元素上的事件
    50                     element.on('blur keyup change', function() {
    51                         scope.$apply(setViewValue);
    52                     });
    53 
    54                     setViewValue();
    55 
    56                     // 更新模型上的视图值
    57                     function setViewValue() {
    58                         var val = element.val();
    59                         ngModel.$setViewValue(val);
    60                     }
    61                 }  
    62             }
    63         })

     ---以上代码使用示例为 <input def-laydate type="text" id="id1" ng-model="startTime"  max-date="{{model.max}}" min-date="{{model.min}}"/> min-date,max-date属性按需添加。

    这样的指令一般情况下已经可以满足使用,但是在结合ngDialog使用时出现了问题:layDate在初始化中getElementById 获取元素时,弹窗中的html内容还没有持到页面的结点树中,故而报错。

    于是希望指令的link代码可以在弹窗渲染后再执行,查找资料后,在指令中引入了$timeout:

    app.directive('ngcLayDate', function($timeout) {
                return {
                    require: '?ngModel',
                    restrict: 'A',
                    scope: {
                        ngModel: '=',
                        maxDate:'@',
                        minDate:'@'
                    },
                    link: function(scope, element, attr, ngModel) {
                        var _date = null,_config={};
                         // 渲染模板完成后执行
                        $timeout(function(){ 
                            // 初始化参数 
                            _config = {
                                elem: '#' + attr.id,
                                format: attr.format != undefined && attr.format != '' ? attr.format : 'YYYY-MM-DD',
                                max:attr.hasOwnProperty('maxDate')?attr.maxDate:'',
                                min:attr.hasOwnProperty('minDate')?attr.minDate:'',
                                choose: function(data) {
                                    scope.$apply(setViewValue);
                                    
                                },
                                clear:function(){
                                   ngModel.$setViewValue(null);
                                }
                            };
                            // 初始化
                            _date= laydate(_config);
    
                            // 监听日期最大值
                            if(attr.hasOwnProperty('maxDate')){
                                attr.$observe('maxDate', function (val) {
                                    _config.max = val;
                                })
                            }
                            // 监听日期最小值
                            if(attr.hasOwnProperty('minDate')){
                               attr.$observe('minDate', function (val) {
                                    _config.min = val;
                                })
                            }
                           
                            // 模型值同步到视图上
                            ngModel.$render = function() {
                                element.val(ngModel.$viewValue || '');
                            };
    
                            // 监听元素上的事件
                            element.on('blur keyup change', function() {
                                scope.$apply(setViewValue);
                            });
    
                            setViewValue();
    
                            // 更新模型上的视图值
                            function setViewValue() {
                                var val = element.val();
                                ngModel.$setViewValue(val);
                            }
                        },0);  
                    }
                };
            })

    OK,问题解决。解决问题的过程伴随着查资料的过程,是一步步完善的。也希望大家在遇到同样的问题时少走弯路。

    另:码字不易,转载请注明出处。

    或取诸怀抱,晤言一室之内;或因寄所托,放浪形骸之外。
  • 相关阅读:
    Java之Map遍历方式性能分析:ketSet与entrySet
    Java之null保留字
    Java之&0xff用法解析以及原码、反码、补码相关知识
    Android之使用apt编写编译时注解
    Android之ViewPager.PageTransformer
    Android Studio利用javac导出Api文档
    06_Java多线程、线程间通信
    05_Java异常(Exception)
    04_Java面向对象特征之继承与多态
    03_Java面向对象特征: 封装性
  • 原文地址:https://www.cnblogs.com/e50000/p/5663806.html
Copyright © 2011-2022 走看看