В Backbone.js управление состоянием моделей и отслеживание изменений данных играют ключевую роль для построения реактивных и отзывчивых интерфейсов. Основные механизмы для этого — dirty checking и change tracking, которые позволяют определить, были ли изменения в модели, и реагировать на них соответствующим образом.
Модель (Backbone.Model) представляет собой структуру
данных с набором атрибутов и методами для управления ими. Каждый объект
модели хранит свои атрибуты в приватном объекте attributes.
Любое изменение атрибутов осуществляется через методы set и
unset, а также через конструктор при создании модели.
Пример создания модели:
var Task = Backbone.Model.extend({
defaults: {
title: '',
completed: false
}
});
var task = new Task({ title: 'Learn Backbone.js' });
Dirty checking — это процесс определения того, изменились ли атрибуты
модели по сравнению с их предыдущим состоянием. Backbone реализует это
через внутреннюю структуру changedAttributes и события
change.
Основные моменты:
set принимает объект с новыми значениями
атрибутов.changed.change, а также события для конкретных атрибутов
(change:attributeName).Пример:
task.on('change:title', function(model, value) {
console.log('Title changed to:', value);
});
task.set({ title: 'Master Backbone.js' });
// Выведет: Title changed to: Master Backbone.js
Метод hasChanged позволяет проверить, были ли изменения
в модели с момента последнего сохранения:
task.hasChanged(); // true
task.hasChanged('title'); // true
task.changedAttributes(); // { title: 'Master Backbone.js' }
Change tracking — более детализированное отслеживание изменений атрибутов. Backbone предоставляет API для работы с предыдущими и текущими значениями:
previous(attribute) возвращает значение атрибута до
последнего изменения.previousAttributes() возвращает объект со всеми
предыдущими атрибутами модели.Пример:
console.log(task.previous('title')); // 'Learn Backbone.js'
console.log(task.previousAttributes());
// { title: 'Learn Backbone.js', completed: false }
Это позволяет реализовывать сложные сценарии, например, откат изменений или условное реагирование на изменения только в определённых атрибутах.
Backbone.js использует событийную модель для оповещения об изменениях:
change — вызывается при любом изменении модели.change:attributeName — вызывается при изменении
конкретного атрибута.sync — вызывается после успешного сохранения модели на
сервере.invalid — вызывается, если модель не прошла
валидацию.Пример подписки на несколько событий:
task.on({
'change:title': function(model, value) {
console.log('Title changed:', value);
},
'change:completed': function(model, value) {
console.log('Completed changed:', value);
},
'change': function() {
console.log('Some attribute changed');
}
});
Коллекции (Backbone.Collection) также поддерживают
отслеживание изменений через события моделей:
update — вызывается при добавлении, удалении или
изменении моделей в коллекции.change — пробрасывается от модели к коллекции.Пример:
var Tasks = Backbone.Collection.extend({
model: Task
});
var tasks = new Tasks([task]);
tasks.on('change', function(model) {
console.log('A task has changed:', model.toJSON());
});
task.set({ completed: true });
// Выведет: A task has changed: { title: 'Master Backbone.js', completed: true }
При работе с большими коллекциями или моделями с множеством атрибутов важно минимизировать лишние события:
silent: true при массовых
изменениях, чтобы отложить события.model.trigger('change') вручную после
завершения изменений.listenTo вместо on для
автоматического снятия подписок при уничтожении объектов.Пример массового обновления с минимизацией событий:
task.set({ title: 'Finalize Backbone.js', completed: true }, { silent: true });
task.trigger('change'); // одно событие вместо двух
Dirty checking и change tracking обеспечивают Backbone.js простой, но мощный способ отслеживания изменений в данных. Они формируют основу реактивной архитектуры, позволяя моделям и коллекциям уведомлять представления о любых изменениях и обеспечивать синхронизацию состояния интерфейса с данными. Понимание этих механизмов критично для построения масштабируемых веб-приложений с Backbone.js.