修改observableArray中可观察值的值

时间:2018-04-28 12:00:15

标签: knockout.js

我有一个包含7天(星期)和currentDate的数组。当currentDate低于week数组的最低值时,我想更改数组中每个元素的日期并将它们移动1周。

这是我的代码。订阅工作正常,但1周的转移似乎根本不起作用。我做错了什么?

在这里小提琴:https://jsfiddle.net/rhsr0m9L/

import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

@NgModule({
 //...
imports: [
     //...
   FontAwesomeModule
  ],
})
export class AppModule { }  

1 个答案:

答案 0 :(得分:1)

您的ko视图模型完全正确。使用momentjs库只有两个问题。 基于文档的时刻,对象是可变的,这意味着当您初始化week数组时,您实际上每次都在修改currentDate并将其引用推送到week数组(日期显示正确我相信因为ko因性能原因而缓存视图。这就是为什么开始所有日期都有灰色背景,因为你周的所有日期都是同一个对象实例。然后当你改变你的日期时,它只是一团糟,因为forEach循环增加-7天会在同一时刻反对7次:)这就是为什么你会得到七天的同一天周以间隔时间间隔。

另一个问题是检查日期是否等于或等于。根据文档,您应使用.isBefore(..).isSame(..)方法,而不是<==

我更新了你应该按预期工作的小提琴https://jsfiddle.net/rhsr0m9L/1/

&#13;
&#13;
  function CalDay(date, total) {
    var self = this;
    this.date = ko.observable(date);
    this.total = ko.observable(total);
    this.dateFormatted = ko.computed(function() {
      return this.date().format('ddd Do');
    }, this);
  }

  var TimesheetViewModel = function() {
    var self = this;
    this.currentDate = ko.observable(moment().startOf('day'));
    this.week = ko.observableArray([]);

    this.incDay = function() {
      this.currentDate(moment(this.currentDate()).add(1, 'days'));
    };

    this.decDay = function() {
      this.currentDate(moment(this.currentDate()).add(-1, 'days'));
    };

    this.gotoToday = function() {
      this.currentDate(moment().startOf('day'));
    };

    this.isToday = ko.pureComputed(function() {
      return !this.currentDate().isSame(moment().startOf('day'));
    }, this);

    self.currentDate.subscribe(function() {
      if (self.week()[0] != undefined) {
        if (self.currentDate().isBefore(self.week()[0].date())) {
          self.week().forEach(function(d) {
            console.log(d.date())
            d.date(d.date().add(-7, 'days'))
          })
        }
      }
    });

    [0, 1, 2, 3, 4, 5, 6].forEach(function(i) {
      var temp = moment(self.currentDate());
      self.week.push(new CalDay(temp.startOf('isoWeek').startOf('day').add(i, 'days'), i));
    });
  };

  ko.applyBindings(new TimesheetViewModel());
&#13;
body {
  padding: 20px;
  font-family: Helvetica;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
}

.lightgray-back {
  background-color: lightgray;
}

#timesheets_list>tr>th {
  padding-left: 30px;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="block" id="day-table">
  <div class="infoline mt20">

    <div class="date-sel">
      <div class="input-group narrow-input">
        <span class="input-group-addon" id="calendar-link">
                      <i class="fa fa-calendar"></i>
                    </span>
        <label class="form-control" data-bind="text: currentDate" id="list_date" readonly="true" type="text"></label>
        <button data-bind="click: gotoToday, visible: isToday" id="calendar_today">
        Jump to Today
        </button>
      </div>
    </div>

  </div>
  <div class="weekline mt20">
    <button data-bind="click: decDay">
                Back
                </button>
    <button data-bind="click: incDay">
                Forward
                </button>
  </div>

  <div class="row">
    <div class="col-xs-8 col-xs-offset-2">
      <div class="table-responsive">
        <table class="table">
          <thead id="timesheets_list">
            <tr>
              <th data-bind="text: week()[0].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[0].date()) }"></th>
              <th data-bind="text: week()[1].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[1].date()) }"></th>
              <th data-bind="text: week()[2].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[2].date()) }"></th>
              <th data-bind="text: week()[3].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[3].date()) }"></th>
              <th data-bind="text: week()[4].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[4].date()) }"></th>
              <th data-bind="text: week()[5].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[5].date()) }"></th>
              <th data-bind="text: week()[6].dateFormatted(), css: { 'lightgray-back': currentDate().isSame(week()[6].date()) }"></th>
              <th>Total</th>
            </tr>
          </thead>
          <tbody>
            <tr></tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>

</div>
&#13;
&#13;
&#13;