Knockout的日期格式问题以及同步修改的breeze.js entityAspect的同步问题

时间:2013-06-08 15:59:10

标签: date knockout.js breeze

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

我正在使用Breeze,Knockout。有一个表格,我希望显示短日期。

<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时,我认为我无法转换。我正在扩大通话中的表格数量&amp;你不能两者兼顾。

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

以为我会看到蜂巢头脑的想法......

3 个答案:

答案 0 :(得分: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" />

每当更新后备可观察的“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”。

我希望这有帮助!

答案 1 :(得分:1)

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

我的情况有点不同。我的日期以JSON字符串形式出现(Ex.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 = "";
        }
    }
};

use(dateFormats optional with defaults)

<input type="text" data-bind="date: trueDate, dateFormats: { from: 'YYYY-MM-DDTHH:mm:ss', to: 'YYYY/MM/DD' }" />

答案 2 :(得分: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);
        }
    };

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