6

好的,所以这不是第一次,但我很难约会。;-)

我正在使用微风,淘汰赛。有一个我希望显示短日期的表格。

<input name="start" data-bind="value: start" class="date required" required="required" placeholder="mm/dd/yyyy" style=" width:142px"> 

产生一个长日期时间:2011 年 8 月 31 日星期三 20:00:00 GMT-0400(东部夏令时间)。

创建一个格式化所需短日期的方法可以实现创建短日期的目标,但我的 modelContext 不知道任何更改通知。所以我的对象不会通知屏幕更改。我可以通过尝试在点击时通知 dataContext 等来解决这个问题,但我希望在转换过程中不会丢失。

function positionInitializer(posit) {

    var shortDate = function (date) {
        return date && moment.utc(date).isValid() ? moment.utc(date).format('L') : "";
    };

    posit.start = ko.observable(shortDate(posit.start()));
}

有没有关于如何做到这一点的体面例子?

我认为当我调用查询 b/c 时我无法转换我正在扩大我调用中的表格数量,你不能两者都做。

        var query = EntityQuery.from('Positions')
        .where('id', '==', id)
        .expand('Company, Projects')
        .orderBy(orderBy.positions);

我想我会看看蜂巢思维是怎么想的……

4

3 回答 3

7

使用 Knockout 处理日期格式有几个不错的选择。

可写计算

您可以为您的日期值创建一个可写计算并在那里进行所有格式化和解析。例如:

var myViewModel = function(){
    var self=this;
    self.trueDate = ko.observable(new Date());
    self.formattedDate = ko.computed({
        read: function(){
            return moment(self.trueDate()).format('L');
        },
        write: function(value){
            self.trueDate(moment(value).toDate());
        }
    });
}

<input type="text" data-bind="value: formattedDate" />

任何时候支持的 observable "trueDate" 被更新,它的观察者都会被提醒。

自定义绑定

另一种方法是构建自定义数据绑定,以在绑定期间格式化数据并保持视图模型简单。

var myViewModel = function(){
    var self=this;
    self.trueDate = ko.observable(new Date());
}

ko.bindingHandlers.dateString = {
    init : function(element, valueAccessor) {
        //attach an event handler to our dom element to handle user input
        element.onchange = function(){
            var value = valueAccessor();//get our observable
            //set our observable to the parsed date from the input
            value(moment(element.value).toDate());
        };
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
        var value = valueAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(value);
        if (valueUnwrapped) {
             element.value = moment(valueUnwrapped).format('L');
        }
    }
};

(请记住,上面的绑定代码未经测试,不检查无效输入等)

然后你的绑定将是

<input type="text" data-bind="dateString : trueDate" />

我更喜欢自定义绑定方法,因为它可以轻松地用于其他日期和视图模型。自定义绑定还可以读取该元素上的其他绑定,因此您可以将日期格式字符串配置为绑定,而不是将其硬编码为“L”。

我希望这有帮助!

于 2013-06-08T17:59:06.423 回答
1

@RyanRahlf 您的回答给了我一些灵感,因此为您的解决方案提供了可配置的格式和日期验证插件。

我的情况有点不同。我的日期以 JSON 字符串的形式出现(例如 2013-08-02T00:00:00),所以我需要两种格式,一种来自 JSON,另一种是显示的内容(用户友好)

ko.bindingHandlers.date = {
    init: function (element, valueAccessor, allBindingsAccessor) {
        var formats = allBindingsAccessor().dateFormats || { from: "", to: "" };
        element.onchange = function () {
            var observable = valueAccessor();
            var value = moment(element.value)
            if (value && value.isValid()) {
                //if format is not set then assume observed is a js date
                if (formats.from) {
                    observable(value.format(formats.from));
                }
                else {
                    observable(value.toDate());
                }
            }
            else {
                observable("");
                //ensures element is blank when invalid input is attempted
                if (element.value) element.value = "";
            }
        };
    },
    update: function (element, valueAccessor, allBindingsAccessor) {
        var formats = allBindingsAccessor().dateFormats || { from: "", to: "MM/DD/YYYY" };
        var observable = valueAccessor();
        var valueUnwrapped = ko.utils.unwrapObservable(observable);
        if (valueUnwrapped) {
            element.value = moment(valueUnwrapped).format(formats.to);
        }
        else {
            element.value = "";
        }
    }
};

使用(dateFormats 可选,默认值)

<input type="text" data-bind="date: trueDate, dateFormats: { from: 'YYYY-MM-DDTHH:mm:ss', to: 'YYYY/MM/DD' }" />
于 2013-08-02T21:37:21.097 回答
0

如果您已经在使用 jQuery datepicker 并且不想添加另一个 javascript 库,您可以使用:

ko.bindingHandlers.textDate = {
        update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            var value = valueAccessor(),
                allBindings = allBindingsAccessor(),
                valueUnwrapped = ko.utils.unwrapObservable(value),
                pattern = allBindings.datePattern || $.datepicker._defaults.dateFormat,
                valueFormatted = $.datepicker.formatDate(pattern, valueUnwrapped);

            $(element).text(valueFormatted);
        }
    };

但是,它仅适用于日期类型。

于 2013-09-25T08:46:20.943 回答