Date/time manipulation

Backbone.js не предоставляет встроенных утилит для работы с датой и временем, однако его архитектура моделей, коллекций и событий позволяет эффективно интегрировать сторонние библиотеки и собственные методы для манипуляции временными данными. Основной принцип заключается в хранении данных в моделях и обеспечении их синхронизации с представлениями через события.


Модели и поля даты

Модель Backbone представляет собой контейнер для данных и бизнес-логики. Для работы с датой и временем поле модели должно хранить объект Date или строку в формате ISO 8601:

var Event = Backbone.Model.extend({
    defaults: {
        title: '',
        startDate: null,
        endDate: null
    },

    initialize: function() {
        if (!(this.get('startDate') instanceof Date)) {
            this.set('startDate', new Date(this.get('startDate')));
        }
        if (!(this.get('endDate') instanceof Date)) {
            this.set('endDate', new Date(this.get('endDate')));
        }
    }
});

В этом примере при инициализации модели происходит конвертация входных значений в объекты Date, что обеспечивает единый формат для всех операций с временем.


Форматирование даты и времени

Для удобного отображения и форматирования дат удобно использовать сторонние библиотеки, такие как Moment.js или date-fns. Backbone не ограничивает формат хранения данных, поэтому модели могут возвращать отформатированные значения через вычисляемые свойства:

var EventView = Backbone.View.extend({
    render: function() {
        var start = this.model.get('startDate');
        var end = this.model.get('endDate');
        this.$el.html(
            this.model.get('title') + ': ' +
            start.toLocaleString() + ' - ' +
            end.toLocaleString()
        );
        return this;
    }
});

Методы toLocaleString, toISOString и другие позволяют представлять дату в требуемом формате без изменения внутреннего состояния модели.


Манипуляции с датой в моделях

Часто возникает необходимость добавлять или вычитать дни, часы, минуты. Это выполняется через методы Date:

var Event = Backbone.Model.extend({
    addDays: function(days) {
        var date = new Date(this.get('startDate'));
        date.setDate(date.getDate() + days);
        this.set('startDate', date);
    },

    addHours: function(hours) {
        var date = new Date(this.get('startDate'));
        date.setHours(date.getHours() + hours);
        this.set('startDate', date);
    }
});

Такие методы позволяют централизованно управлять временными данными, не нарушая архитектуру MVC.


Слежение за изменениями даты

Backbone позволяет отслеживать изменения в атрибутах модели с помощью событий change или change:attribute:

var event = new Event({ title: 'Meeting', startDate: '2025-12-29T10:00:00Z' });

event.on('change:startDate', function(model, value) {
    console.log('Начало события изменилось на:', value);
});

event.set('startDate', new Date('2025-12-30T12:00:00Z'));

События обеспечивают автоматическое обновление представлений при изменении даты или времени, что упрощает синхронизацию интерфейса с данными.


Работа с коллекциями и временными фильтрами

Коллекции Backbone позволяют хранить группы моделей и выполнять фильтрацию по дате:

var Events = Backbone.Collection.extend({
    model: Event,

    upcoming: function() {
        var now = new Date();
        return this.filter(function(event) {
            return event.get('startDate') > now;
        });
    }
});

var events = new Events([
    { title: 'Event 1', startDate: new Date('2025-12-30T10:00:00Z') },
    { title: 'Event 2', startDate: new Date('2025-12-28T09:00:00Z') }
]);

var upcomingEvents = events.upcoming();

Использование методов коллекций filter, map, sortBy позволяет гибко обрабатывать временные данные.


Сериализация и хранение даты

При отправке данных на сервер через Backbone.sync рекомендуется преобразовывать объекты Date в строки ISO 8601:

var Event = Backbone.Model.extend({
    toJSON: function() {
        var attrs = _.clone(this.attributes);
        if (attrs.startDate instanceof Date) {
            attrs.startDate = attrs.startDate.toISOString();
        }
        if (attrs.endDate instanceof Date) {
            attrs.endDate = attrs.endDate.toISOString();
        }
        return attrs;
    }
});

Такое представление обеспечивает совместимость с REST API и стандартными форматами JSON.


Интеграция с внешними библиотеками

Backbone легко сочетается с библиотеками для работы с датами:

  • Moment.js — удобная работа с форматированием, локализацией и арифметикой времени.
  • date-fns — функциональные методы для добавления, вычитания и форматирования дат.
  • Luxon — поддержка временных зон и объектов DateTime.

Пример с Moment.js:

var EventView = Backbone.View.extend({
    render: function() {
        var start = moment(this.model.get('startDate')).format('YYYY-MM-DD HH:mm');
        var end = moment(this.model.get('endDate')).format('YYYY-MM-DD HH:mm');
        this.$el.html(this.model.get('title') + ': ' + start + ' - ' + end);
        return this;
    }
});

Использование сторонних библиотек расширяет возможности Backbone, сохраняя простоту и модульность архитектуры.


Итоговая архитектура

Работа с датой и временем в Backbone строится на следующих принципах:

  • Хранение даты в модели в формате Date для единообразных операций.
  • Использование событий для синхронизации изменений с представлениями.
  • Расширение функционала моделей методами для манипуляции временем.
  • Преобразование даты в стандартные форматы при сериализации.
  • Интеграция с внешними библиотеками для удобного форматирования и вычислений.

Такой подход обеспечивает чистую архитектуру, гибкость и масштабируемость при работе с временными данными в Backbone.js.