Angularjs中使用layDate日期控件解决其与ng-model使用时的冲突
ayDate 控件地址:http://laydate.layui.com/
前情:原来系统中使用的日期控件是UI bootstrap(地址:https://angular-ui.github.io/bootstrap/)里的。后来因为各种原因,要换掉UI bootstrap中的日期控件,改用layDate日期控件。
1.第一种情况
解决思路:将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属性按需添加。
3.第三种
这样的指令一般情况下已经可以满足使用,但是在结合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,问题解决。解决问题的过程伴随着查资料的过程,是一步步完善的。也希望大家在遇到同样的问题时少走弯路
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
原文链接:http://www.cnblogs.com/e50000/p/5663806.html
- 上一篇: 日期插件layDate的使用
- 下一篇: LayDate 时间选择插件的使用介绍