我正在开发一个自定义 bindingHandlers 来在输入框中显示/编辑日期。每当用户输入无效日期时,我想清除输入框。
注意:输入日期的输入框是可观察的(从微风中查询)。
这是我的实际实现:
ko.bindingHandlers.dateRW = {
//dateRW --> the 'read-write' version used both for displaying & updating dates
init: function (element, valueAccessor, allBindingsAccessor) {
var observable = valueAccessor();
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var value = $(element).val();
var dateFormatted = moment.utc(value, "DD/MM/YYYY");
if (dateFormatted!=null && dateFormatted.isValid())
observable(dateFormatted.toDate())
else {
observable(null);
}
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var date = (typeof value !== 'undefined') ? moment.utc(value) : null;
var dateFormatted = (date != null) ? date.format('DD/MM/YYYY') : '';
$(element).val(dateFormatted);
}
};
运行良好的示例:
- 用户正在输入 25/12/2013 >> 日期有效
- 接下来,用户正在输入 1234 >> 日期无效 >> 输入框被清除
- 接下来,用户输入 01/04/2013 >> 日期有效
不工作的例子:
- 用户正在输入 1234 >> 日期无效 >> 输入框被清除
- 接下来,用户输入 5678 >> 日期(再次!)无效 >> 输入框不再被清除!!
输入框不再被清除的原因是因为在上一步中 observable 已经设置为 null 并且我们知道如果 observable 没有更改其值,则不会触发更新。
我发现的解决方法如下:强制两次连续更新(未定义+空)。
ko.bindingHandlers.dateRW = {
//dateRW --> the 'read-write' version used both for displaying & updating dates
init: function (element, valueAccessor, allBindingsAccessor) {
var observable = valueAccessor();
//handle the field changing
ko.utils.registerEventHandler(element, "change", function () {
var value = $(element).val();
var dateFormatted = moment.utc(value, "DD/MM/YYYY");
if (dateFormatted!=null && dateFormatted.isValid())
observable(dateFormatted.toDate())
else {
observable(undefined);
observable(null);
}
});
},
update: function (element, valueAccessor, allBindingsAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var date = (typeof value !== 'undefined') ? moment.utc(value) : null;
var dateFormatted = (date != null) ? date.format('DD/MM/YYYY') : '';
$(element).val(dateFormatted);
}
};
我不喜欢那样进行。也许有更好的方法?
谢谢。