如何处理循环中的时刻日期?

时间:2015-11-08 18:28:51

标签: javascript knockout.js momentjs

我很难过,想出这个。我希望根据指定的时间段在两个日期获得差异。

我在片段下方。每当我单击按钮时,它应该使用差异填充数组(基于指定的时间段)。

但是,目前正在发生的事情是,一旦我点击按钮,就会填充相同的日期。有什么想法吗?



var fooObj = function(){
    var self = this;
    self.month = ko.observable();
    self.formatted = ko.computed(function() {
        return month().format('ddd, DD MMM YYYY');
    });
};

var vm = (function() {
    var startDate = ko.observable(moment([2015, 10, 1])),
        startDateFormat = ko.computed(function() {
            return startDate().format('ddd, DD MMM YYYY');
        }),
		endDate = ko.observable(startDate().add(5, 'days')),
        endDateFormat = ko.computed(function() {
            return endDate().format('ddd, DD MMM YYYY');
        }),
        dateDiff = endDate().diff(startDate(), 'days'),
        foo = ko.observableArray(),
        test = function(){
            for(var i = 0; i<=5; i++){
                foo.push(startDate().add(1, 'days'));
            }
        };
    
    return {
        startDate: startDate,
        endDate: endDate,
        foo: foo,
        test: test,
        dateDiff: dateDiff,
        startDateFormat: startDateFormat,
        endDateFormat: endDateFormat
    };
}());

ko.applyBindings(vm);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre><br />
<button data-bind="click: $root.test">Click me for test</button>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:4)

您似乎陷入了一个微妙的语法陷阱,这是一个容易犯的错误。 moment.js提供了方法链语法,它提供了您案例中混淆的来源。

例如,当您以这种方式设置endDate的默认值时,基于startDate

endDate = ko.observable(startDate().add(5, 'days'))

您没有得到预期的结果,因为方法链接会为您提供原始值,然后再添加5天。

相反,如果您克隆moment对象然后添加,您将得到我相信您期望的结果:

endDate = ko.observable(moment(startDate()).add(5, 'days'))

并且您还需要在test方法的循环中执行相同的操作:

foo.push(moment(startDate()).add(i, 'days')); // use index var i for number of days

完整的可运行示例如下:

var vm = (function() {
    var startDate = ko.observable(moment([2015, 10, 1])),
        startDateFormat = ko.computed(function() {
            return startDate().format('ddd, DD MMM YYYY');
        }),
        // make sure to clone startDate before add
	endDate = ko.observable(moment(startDate()).add(5, 'days')),
        endDateFormat = ko.computed(function() {
            return endDate().format('ddd, DD MMM YYYY');
        }),
        dateDiff = endDate().diff(startDate(), 'days'),
        foo = ko.observableArray(),
        test = function(){
            for(var i = 0; i<=5; i++){
                // make sure to clone startDate before adding days
                foo.push(moment(startDate()).add(i, 'days'));  // use index var i for number of days
            }
        };
    
    return {
        startDate: startDate,
        endDate: endDate,
        foo: foo,
        test: test,
        dateDiff: dateDiff,
        startDateFormat: startDateFormat,
        endDateFormat: endDateFormat
    };
}());

ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<pre data-bind="text: ko.toJSON($root, null, 2)"></pre><br />
<button data-bind="click: $root.test">Click me for test</button>