首页 > 技术文章 > easyui-datetimebox : formatter和onchange事件重复执行、多次执行、返回的日期不正确的坑

northwest332 2021-11-05 16:36 原文

背景介绍

刚入冬就在easyui-datetimebox的坑底游了个冬泳。

需求是这样的:要求有日期时间选择框,选中以后返回格式(dd)hh:mm,并且每次时间发生变化,就要重新执行查询数据的方法。

这个格式就有点奇怪,为了获取到完整的时间,我还要加个全局变量去存储时间。

原始代码

$('#datetime').datetimebox({
	required: false,
	onChange: function() {
		// 时间发生变化时,执行查询方法
		queryMethod();
	},
	formatter: function(date) {
		// 获取日时分 格式为(dd)
		var d = Number(date.getDate())<10? ("0"+date.getDate()):date.getDate();
		var h = Number(date.getHours())<10? ("0"+date.getHours()):date.getHours();
		var min = Number(date.getMinutes())<10? ("0"+date.getMinutes()):date.getMinutes();
		
		// 拼接需要返回的数据格式
		var formatStr = "("+d+")"+d+":"+h+":"+m;
		
		// 拼接需要作为全局变量存储的时间
		// 注意month的范围是0-11
		// 当初谁想出来的月份从0开始数啊
		var mt = Number(date.getMonth())+1;
		if(mt<10){
			mt = "0"+mt.toString();
		}
		// 常规的yyyy-mm-dd hh:mm:ss 格式 秒数为00是特殊需求
		time = date.getFullYear()+"-"+mt+"-"+d+" "+ h + ":" + m+":00";
		
		// 返回需要的串
		return formatStr;
	}
});

然后我发现我无论选中了什么时间,返回的日期都是当天。

并且Onchange里面的方法执行了多次

搜了一下,看了看easyui官方文档

发现datebox里面有一个默认的解析时间字符串的方法:

参数s是formatter函数返回的字符串,我返回的字符串是(dd)hh:mm,这个格式无法被new Date(s)解析,所以每次都返回一个当前日期new Date()。

所以需要修改一下这个默认的parser方法,让new Date(s)能够解析成功。

parser: function(s) {
	var t;
	// 全局变量中的时间
	if (time && time != "") {
		t = time;
	}
	if (s.indexOf("(") > -1) {
		// 如果当前时间是我们的formatter方法返回的字符串
		// 这个字符串无法被解析
		// 所以就去解析全局变量那个时间
		t = Date.parse(t);
	} else {
		// 如果不是,就解析传过来的字符串
		t = Date.parse(s);
	}
	if (!isNaN(t)) {
		return new Date(t);
	} else {
		return new Date();
	}
}

这样就基本可以完事了.

但是onchange方法刚开始加载datetimebox的时候会执行一次

这个问题很好处理,给datetimebox添加一个变量isFirst = true;
然后在onchange方法里写,if(isFirst){isFirst = false, return;};

问题解决。

隐隐约约记得用easyui的时候,还遇到了另一个坑,想起来再写吧。

推荐阅读