3

当我深入研究 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() 的结果的地方保持可观察的“影子”。

4

4 回答 4

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)
于 2012-10-20T02:35:31.037 回答
0

您需要使用 ko.computed 而不是 ko.observable。见下文。Observables 通常只包含值或其他 observables。Computed 用于进行计算

   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
    })
于 2012-10-19T10:53:51.013 回答
0

经过一些研究,我发现扩展器完全符合我的要求,例如,它们可以在设置后立即自动转换可观察对象上的值。

于 2012-10-19T11:01:54.037 回答
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'));
    }
});
于 2012-10-19T21:21:08.277 回答