Angularjs中使用layDate日期控件示例


Posted in Javascript onJanuary 11, 2017

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

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

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

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

指令具体代码:

/**
     * 使用示例
     * <input def-laydate type="text" id="id1" ng-model="startTime"/>
     */
    app
    .directive('defLaydate', function() {
      return {
        require: '?ngModel',
        restrict: 'A',
        scope: {
          ngModel: '='
        },
        link: function(scope, element, attr, ngModel) {
          var _date = null,_config={};
          
            // 初始化参数 
          _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);

         
          
          // 模型值同步到视图上
          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);
          }
        } 
      }
    })

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

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

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

app.directive('defLaydate', function() {
      return {
        require: '?ngModel',
        restrict: 'A',
        scope: {
          ngModel: '=',
          maxDate:'@',
          minDate:'@'
        },
        link: function(scope, element, attr, ngModel) {
          var _date = null,_config={};
          
            // 初始化参数 
          _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);
          }
        } 
      }
    })

 ---以上代码使用示例为 <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,问题解决。解决问题的过程伴随着查资料的过程,是一步步完善的。也希望大家在遇到同样的问题时少走弯路

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

Javascript 相关文章推荐
JQuery文本框高亮显示插件代码
Apr 02 Javascript
Extjs TimeField 显示正常时间格式的代码
Jun 28 Javascript
jquery获取选中的文本和值的方法
Jul 08 Javascript
javascript实现俄罗斯方块游戏的思路和方法
Apr 27 Javascript
js实现的简洁网页滑动tab菜单效果代码
Aug 24 Javascript
jquery+json实现数据二级联动的方法
Nov 28 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
Oct 10 Javascript
微信小程序 ecshop地址三级联动实现实例代码
Feb 28 Javascript
javascript标准库(js的标准内置对象)总结
May 26 Javascript
微信小程序使用map组件实现解析经纬度功能示例
Jan 22 Javascript
浅谈vue限制文本框输入数字的正确姿势
Sep 02 Javascript
关于AngularJS中几种Providers的区别总结
May 17 Javascript
web打印小结
Jan 11 #Javascript
微信小程序 常见问题总结(4058,40013)及解决办法
Jan 11 #Javascript
jQuery插件JWPlayer视频播放器用法实例分析
Jan 11 #Javascript
AngularJS中的缓存使用
Jan 11 #Javascript
AngularJS中的按需加载ocLazyLoad示例
Jan 11 #Javascript
ajax的分页查询示例(不刷新页面)
Jan 11 #Javascript
JavaScript实现大图轮播效果
Jan 11 #Javascript
You might like
使用PHP维护文件系统
2006/10/09 PHP
php 解决旧系统 查出所有数据分页的类
2012/08/27 PHP
浅谈php serialize()与unserialize()的用法
2013/06/05 PHP
php绘图中显示不出图片的原因及解决
2014/03/05 PHP
PHP7之Mongodb API使用详解
2015/12/26 PHP
PHP实现对数字分隔加千分号的方法
2019/03/18 PHP
jquery实现的超出屏幕时把固定层变为定位层的代码
2010/02/23 Javascript
brook javascript框架介绍
2011/10/10 Javascript
带左右箭头图片轮播的JS代码
2013/12/18 Javascript
angularJS 入门基础
2015/02/09 Javascript
jquery实现触发时更新下拉列表内容的方法
2015/12/02 Javascript
jQuery中选择器的基础使用教程
2016/05/23 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
vue中页面跳转拦截器的实现方法
2017/08/23 Javascript
AngularJs的UI组件ui-Bootstrap之Tooltip和Popover
2018/07/13 Javascript
Vue刷新修改页面中数据的方法
2018/09/16 Javascript
Vue slot用法(小结)
2018/10/22 Javascript
vue计算属性computed、事件、监听器watch的使用讲解
2019/01/21 Javascript
Vue自定义全局Toast和Loading的实例详解
2019/04/18 Javascript
keep-alive不能缓存多层级路由菜单问题解决
2020/03/10 Javascript
vue.js+element 默认提示中英文操作
2020/11/11 Javascript
[54:06]OG vs TNC 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
跟老齐学Python之集合的关系
2014/09/24 Python
在Python程序中操作文件之isatty()方法的使用教程
2015/05/24 Python
Python中tell()方法的使用详解
2015/05/24 Python
用python实现百度翻译的示例代码
2018/03/09 Python
python制作填词游戏步骤详解
2019/05/05 Python
python中对二维列表中一维列表的调用方法
2020/06/07 Python
python Tornado框架的使用示例
2020/10/19 Python
Guess欧洲官网:美国服饰品牌
2019/08/06 全球购物
临床医师专业个人自我评价范文
2013/11/07 职场文书
新娘父亲婚礼致辞
2014/01/16 职场文书
校园安全演讲稿
2014/05/09 职场文书
幼儿园开学报名通知
2015/07/16 职场文书
年终工作总结范文
2019/06/20 职场文书
创业计划书之干洗店
2019/09/10 职场文书