我将DateTextBox用作屏幕中的许多控件之一。我将它们注册到一个位置,然后循环循环将值设置为它们,分别对它们调用set('value', val)
。所有控件的行为均正确,只有DateTextBox不会接受来自服务器的数据。
最初,java的Date被序列化为long(例如1280959200000),但是当我更改为ISO格式(例如“ 2010-08-04T22:00:00.000 + 0000”)时,也不被接受。但是,两者都是new Date()
构造函数可接受的日期格式。
在输出中,我获得ISO格式的日期值:“ 2013-08-04T22:00:00.000Z”,因此输入时也应接受该日期值。
如何使用DateTextBox使其接受JavaScript的Date对象支持的所有格式的值,或者可以从服务器返回的格式之一?
最佳答案
我认为根本的问题是Javascript内置的Date对象仅接受某些格式,而Dojo则依赖于该内置的行为。在工作中,我们有一个类似的问题,很多旧的PHP代码习惯于以Mysql衍生的格式(例如YYYY-MM-DD HH:MM:SS
)传递日期。
当前的解决方法是子类dijit/form/DateTextBox
,这也使我们可以进行一些UI改进。当某些东西试图设置一个还不是Date
对象的值并且看起来像MySQL日期时间时,此代码将其重新格式化以匹配ISO-8601并继续传递。
DateTextBox的自定义版本的Dojo 1.9代码:
define([
"dojo/_base/declare",
"dojo/_base/lang",
"dojo/_base/array",
"dijit/form/DateTextBox"
], function(declare, lang, array, DateTextBox){
var clazz = declare([DateTextBox], {
_mysqlStyleExp : /^(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})$/,
postMixInProperties: function(){ // change value string to Date object
this.inherited(arguments);
this.constraints.datePattern = "yyyy-MM-dd"; // Affects display to user
},
_convertMysqlDateToIso: function(value){
value = lang.trim(value);
var matches = this._mysqlStyleExp.exec(value);
if(matches !== null){
// Put the "T" in the middle and add fractional seconds with UTC
// timezone
// If your MySQL dates are NOT in UTC, obviously this will screw things up!
return matches[1] + "T" + matches[2] + ".000Z";
}else{
return null;
}
},
_setValueAttr : function(/*Date|String*/ value, /*Boolean?*/ priorityChange, /*String?*/ formattedValue){
/*
We want to be slightly more permissive in terms of the strings that can be set in order to support
older code... But someday it'd be nice to standardize on Date.toJSON, so warn.
*/
if(typeof(value) === "string"){
var isoDate = this._convertMysqlDateToIso(value);
if(isoDate !== null){
console.warn("Converting non-ISO date of "+value);
value = isoDate;
}
}
this.inherited(arguments);
}
});
return clazz;
});
请注意,这仅影响流入Dojo小部件的数据。