backbone.stickit и html-форма: Как сохранить (пропатчить) только измененные атрибуты?

тл;др

Как использовать backbone.stickit с html-формой, чтобы изменить существующую модель, полученную с сервера, и только ИСПРАВИТЬ измененные атрибуты (измененные пользовательским вводом в html-форме) на сервер?

/tl;др

Я использую backbone.stickit в приложении backbone.js для привязки модели к HTML. -форма, которая является частью магистрального представления. Пока это работает нормально, но становится немного сложнее, если я собираюсь сохранить связанную модель. Это потому, что я хочу использовать метод PATCH и отправлять на сервер только измененные атрибуты. Я пытаюсь проиллюстрировать то, что я сделал до сих пор:

Загрузка модели с сервера

user = new User(); //instatiate a new user-model
user.fetch(); //fetching the model from the server

console.log(user.changedAttributes()); // Returns ALL attributes, because model was empty

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

user.fetch({
    success: function (model, response, options) {
        model.set({});
    }
});

user.changedAtrributes(); //Returns now "false"

Сделайте привязки

Теперь я визуализирую свое представление и вызываю метод stickit() для представления, чтобы выполнить привязки:

//Bindings specified in the view:
[...]
bindings: {
  "#username" : "username"
  "#age"      : "age"
}

[...]

//within the render method of the view
this.stickit();

Привязки работают нормально, и моя пользовательская модель обновляется, но changedAttributes() все время остается пустым.

Сохранить модель на сервере

Если пользователь внес все необходимые изменения, модель должна быть сохранена на сервере. Я хочу использовать метод PATCH и отправлять на сервер только измененные атрибуты.

user.save(null, {patch:true}); //PATCH method is used but ALL attributes are sent to the server

OR

user.save(user.changedAttributes(),{patch : true}); 

При втором подходе результаты разные:

  1. если я не использовал обходной путь user.set({}), все атрибуты ИСПРАВЛЯЮТСЯ на сервер
  2. если я использую user.set({}), возвращаемое значение changedAttributes() является «ложным», и все атрибуты помещаются на сервер
  3. если я вызываю user.set("age","123") перед вызовом save(), то только атрибут возраста ИСПРАВЛЯЕТСЯ на сервер

Таким образом, результат 3 - это мое желаемое поведение, но с этим есть 2 проблемы: во-первых, похоже, что он не использует метод set() в модели для обновления атрибутов, если они изменены в html-форме. И во-вторых, если вы вызываете set() с одним атрибутом, а затем с другим, changedAttributes() возвращает только вторые атрибуты.

Возможно, я просто просмотрел что-то в документации по магистральной сети или backbone.stickit, поэтому желаемое поведение не сработало. Есть идеи по этому поводу?


person morten.c    schedule 21.03.2014    source источник


Ответы (1)


ПРИМЕЧАНИЕ. Как выяснилось, проблема не была напрямую связана с backbone.stickit, а скорее с самим backbone.

Решил эту проблему самостоятельно, может быть, это поможет кому-то, кто может наткнуться на этот вопрос:

Backbone отслеживает только неизмененные атрибуты, но не несохраненные атрибуты. Так с

model.changedAttributes();

вы получите только атрибуты модели, которая была изменена с момента последней

model.set("some_attribute","some_value")

Наконец я наткнулся на backbone.trackit, который представляет собой плагин backbone.js, поддерживаемый создателем backbone. придерживаться С помощью этого подключаемого модуля вы можете отслеживать несохраненные атрибуты (все атрибуты, которые изменились с момента последнего model.save()), а затем использовать их в методе сохранения модели. Пример (мой вариант использования):

Backbone.View.extend({
  bindings: {
    "#name" : "name",
    "#age"  : "age"
  },

  initialize: function () {
    this.model = new User();
    this.model.fetch({
      success: function (model, response, options) {
        //this tells backbone.stickit to track unsaved attributes
        model.startTracking(); 
      }
    });
  },

  render: function () {
    this.$el.html(tmpl);
    this.stickit();
    return this;
  },

  onSaveUserToServer: function () {
    //first argument: only unsaved attributes, second argument: tell backbone to PATCH
    this.model.save(this.model.unsavedAttributes(), { patch: true });
  });

});
person morten.c    schedule 21.03.2014