当我深入研究knockout.js的概念时,我很难理解为什么我不能告诉ko.observable如何解析/写出它的值:
dateValue = ko.observable({
read: function (dateString) {
/*convert a date string to an object here for internal storage*/
return Globalize.parseDate(dateString, 'd');
},
write: function (dateObj) {
/*format a date object for output*/
return Globalize.formatDate(dateObj, 'd');
}
})
我知道ko.computed是为了这个目的而存在的,但它们仍然要求我保持一个“阴影”可观察到需要写入read()的结果。
答案 0 :(得分:6)
编写扩展程序以添加formatted
计算的observable,以便您可以读取或写入格式化的值,同时仍然可以访问“原始”未格式化的值。
ko.extenders['date'] = function (target, format) {
var formatted = ko.computed({
'read': function () {
return Globalize.parseDate(target(), format);
},
'write': function (date) {
target(Globalize.format(date, format));
}
});
target.formatted = formatted;
return target;
};
dateValue = ko.observable('10/19/2012').extend({ 'date': 'd' });
// e.g.,
dateValue(); // 10/19/2012
dateValue.formatted(); // Fri Oct 19 2012 00:00:00 GMT-0700 (Pacific Daylight Time)
dateValue.formatted(new Date(2012, 9, 31));
dateValue(); // 10/31/2012
dateValue.formatted(); // Wed Oct 31 2012 00:00:00 GMT-0700 (Pacific Daylight Time)
答案 1 :(得分:0)
您需要使用ko.computed而不是ko.observable。见下文。可观察量通常仅包含值或其他可观察量。计算用于进行计算
dateValue = ko.computed({
read: function () {
/*convert a date string to an object here for internal storage*/
return Globalize.parseDate(this, 'd');
},
write: function (dateObj) {
/*format a date object for output*/
return Globalize.formatDate(dateObj, 'd');
},
owner: viewmodel.dateObservable
})
答案 2 :(得分:0)
经过一些研究后,我发现extenders完全符合我的要求,他们可以例如一旦设置了,就会自动转换observables上的值。
答案 3 :(得分:0)
你可以这样写,没有扩展器:
// dateValue() is the raw date object
// dateValue.formatted() will return the formatted date as well
// as parse a date string and save it back to the observable
dateValue = ko.observable();
dateValue.formatted = ko.computed({
read: function () {
/*format a date object for output*/
return Globalize.formatDate(dateValue(), 'd')
},
write: function (dateObj) {
/*convert a date string to an object here for internal storage*/
dateValue(Globalize.parseDate(dateObj, 'd'));
}
});