Создание массива будних дней с дополнительным свойством и моментом - PullRequest
0 голосов
/ 08 ноября 2019

Используя Momentjs, я создаю массив объектов, month. Внутри этого массива есть два свойства: week и day. week - это просто число, неделя в году, генерируемая моментом. day в настоящее время представляет собой массив дат этой недели, включая промежуточные даты, если это начало или конец месяца (например, диапазон на прошлой неделе будет 27–2, с 27 октября по 2 ноября). Вместо того, чтобы иметь только массив чисел, мне теперь нужно, чтобы свойство days было объектом, со свойством date, которое является датой месяца, и isShoulderDate, логическим значением, которое будет определять, находится ли оно внутри или снаружи. текущего месяца.

Вот как ранее был сгенерирован массив month.

    this.month = [];

    const startWeek = moment(this.selectedDate.from).startOf('month').week();
    const endWeek = moment(this.selectedDate.from).endOf('month').week();

    for (let week = startWeek; week <= endWeek; week++) {
      this.month.push({
        week: week,
        days: Array(7).fill(0).map((n, i) =>
          moment().week(week).startOf('week').clone().add(n + i, 'day').format('D')),
      });
    }

Я попытался изменить свойство days несколькими способами. Моя последняя попытка:

    for (let week = startWeek; week <= endWeek; week++) {
      this.month.push({
        week: week,
        days: Array(7).fill({
          isShoulderDate: null,
        }),
      });
    }

    this.month.forEach((calendarWeek) => {
      calendarWeek.days.map((day, n, i) => {
        day.date = moment().week(calendarWeek).startOf('week').clone().add(n + i, 'day').format('D');
      });
    });

Это просто выводит 3 снова и снова в свойстве date. Я также хотел бы сделать сопоставление при первоначальном заполнении массива, а не иметь дополнительный forEach, чтобы избежать дополнительной итерации.

1 Ответ

2 голосов
/ 08 ноября 2019

Основная проблема заключается в том, что с Array(7).fill({ }) вы используете один объект для заполнения 7 слотов в массиве. Это не 7 объектов, а всего лишь один, на который вы ссылались 7 раз. Поэтому, когда вы позже сделаете обновление для объекта, на который ссылается первый элемент массива, это изменение будет видно в всех элементах массива.

Вот как вы могли бы это сделать. Демоверсия на май 2019 года:

var selectedDate = { from: new Date("2019-05-01") };

this.month = [];

const curMonth = moment(this.selectedDate.from).month(); // Get the month 
const startWeek = moment(this.selectedDate.from).startOf('month').week();
const endWeek = moment(this.selectedDate.from).endOf('month').week();

for (let week = startWeek; week <= endWeek; week++) {
    let dt = moment().week(week).startOf('week');
    this.month.push({
        week: week,
        days: Array.from({length: 7}, (_, i) => ({
            date: dt.add(i ? 1 : 0, 'day').format('D'),
            isShoulderDate: dt.month() !== curMonth,
        })),
    });
}

console.log(month);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.0/moment.min.js"></script>
...