Почему моя базовая модель hasChanged() всегда возвращает false?

С учетом следующего фрагмента:

var m = new Backbone.Model({
    name: 'joshua'
});

m.set('name', 'something else');

Если я теперь звоню m.hasChanged() или m.hasChanged('name'), я получаю false. Почему? Я понимаю, что оба из них должны возвращать true.

m.changedAttributes() также возвращает false.

Вот скрипка, которая иллюстрирует то, что я делаю, и ожидаю: http://jsfiddle.net/9cvVv/88/

EDIT: Похоже, что если вы не передадите { silent: true; } методу set(), тогда он запустит событие change на вашей модели, которое очистит changedAttributes() и т.д. По существу эти свойства отслеживают изменения только с момента последнего запуска события change.

Я прочитал это в документации, но на самом деле не понял его вначале.

Мне это не кажется очень полезным. Я был бы признателен за любое объяснение того, почему это работает так, как оно есть, и лучший способ добиться желаемого результата. (Прохождение {silent: true; } и отказ от использования события change кажется пустой тратой.)

Ответы

Ответ 1

Если вы не передадите { silent: true; } методу set(), тогда он запустит событие change на вашей модели, которое очистит changedAttributes() и т.д. По сути эти свойства отслеживают изменения только с момента последнего change было вызвано событие.

Таким образом, ответ заключается в следующем:

m.set('name', 'something else', {silent: true})

Ответ 2

Этот пост основан на предыдущем поведении старых версий Backbone. hasChanged теперь (от 0.9.10) всегда возвращает true после вызова set(..). Флаг silent больше не действует.

Это смутно маскируется в jsfiddle, связанном с вопросом, который использует CDH-хостингную копию backbone.js, которая всегда использует последнюю версию. Здесь некоторые обновленные jsfiddles, показывающие изменение в поведении:

Ответ 3

Model.set() принимает атрибут хэш как первый аргумент. Попробуйте m.set({'name': 'something else'});. Выполнение m.set('name', 'something') не устанавливает "имя", поэтому никогда не запускает событие change, и ваш вызов hasChanged() возвращает false. Вы всегда можете проверить текущее значение хэша атрибутов путем выхода из системы m.attributes - хотя доступ и манипулирование им напрямую не рекомендуется, поскольку ни одно из событий изменений не срабатывает таким образом.