Обновление измененных атрибутов с помощью backbone.js

Итак, я устанавливаю модель с обновленными атрибутами.

Тогда, на мой взгляд, я слушаю событие изменения для этой модели.

Когда это срабатывает, я думаю, что должен использовать model.changedAttributes? Я передаю ему обратный вызов?

Он должен возвращать хэш всех обновляемых атрибутов или новых? Есть ли вообще знать, какие обновления и какие новые?

Как мне обновиться, если у меня есть этот хэш измененных атрибутов? Разбирайте объект по типу атрибута или я должен просто использовать прослушиватели с более высоким разрешением от перехода?

Спасибо!

Ответы

Ответ 1

Если в вашем представлении показан только один атрибут - например, если он имеет флажок, показывающий некоторый логический атрибут вашей модели, вы должны прослушать событие "change: attribute_name" для этого атрибута, как описано в Документы Backbone.

Если ваше представление более сложное и зависит от нескольких атрибутов модели - например, если это элемент списка "To Do", который имеет элементы "done", "text" и "dueDate", изменить ". В этом случае вы можете либо выбрать обновление всех элементов в каждом событии, либо вы можете использовать changedAttributes(), чтобы определить, какие элементы необходимо обновить.

Чтобы проиллюстрировать...

Обновить атрибуты с помощью событий "change: attribute_name":

Этот стиль хорошо работает для простых представлений, где количество отображаемых атрибутов модели равно < 3 или около того. Более того, и код становится немного громоздким.

model.bind('change:done', function() {
    view.doneElement.checked = model.get('done');
});
model.bind('change:text', function() {
    view.textElement.value = model.get('text');
});
model.bind('change:dueDate', function() {
    view.dueDateElement.value = model.get('dueDate');
});

Обновить все на событиях "change":

Этот стиль хорошо подходит для сложных представлений, которые отображают 4 или более атрибутов (подсчет атрибутов 3/4 - всего лишь приблизительная рекомендация, основанная главным образом на моем личном мнении).

model.bind('change', function() {
    view.doneElement.checked = model.get('done');
    view.textElement.value = model.get('text');
    view.dueDateElement.value = model.get('dueDate');
});

Недостатком этого является то, что для любого изменения обновляется каждый элемент представления. Так, например, если человек отмечает предмет "todo" как "done", текст будет перерисовываться, возможно, потеряв любой выбор, который у них мог быть там. Иногда такая вещь является проблемой, иногда это не так - вам придется решать, на основе того, что именно делает ваш взгляд.

Обновить только то, что было изменено с момента последнего события "change":

Это более тонкая вариация вышеизложенного и сочетает в себе лучшее из обоих подходов. Он обновляет элементы представления, которые нуждаются в обновлении на основе результатов changedAttributes().

model.bind('change', function() {
  var diff = model.changedAttributes();
  for (var att in diff) {
    switch(att) {
      case 'done':
        view.doneElement.checked = model.get('done');
        break;
      case 'text':
        view.textElement.value = model.get('text');
        break;
      case 'dueDate':
        view.dueDateElement.value = model.get('dueDate');
        break;
    }
  }
});

Наконец, я отмечу, что есть еще одна вариация этого вопроса, которая включает в себя наличие хранилища хэша значений, которые он отображает, и передача его в метод changedAttributes(). Это обычно не обязательно, поэтому я не буду утомлять вас подробностями здесь.

Ответ 2

В соответствии с backbone docs событие изменения передает модель и коллекцию моделей обработчику событий.

Событие срабатывает ПОСЛЕ изменений, поэтому переданная модель содержит изменения.

Событие "change" не позволяет вам узнать, какие атрибуты были изменены или добавлены. Если вам нужно сделать действия на основе отдельных атрибутов, используйте события "change: attribute".