backbone.stickit和html-form:如何保存(补丁)只更改属性?

时间:2014-03-21 18:22:37

标签: javascript backbone.js backbone-model backbone-stickit http-patch

TL;博士

如何使用带有html格式的backbone.stickit来更改从服务器获取的现有模型,并仅修改已更改的属性(由html表单中的用户输入更改)到服务器?

/ TL;博士

我在backbone.js应用程序中使用backbone.stickit将模型绑定到作为骨干视图一部分的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()方法来获取需要服务器上的补丁的属性。所以我尝试了这个解决方法,我发现here

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({}) woraround,则所有属性都会获得PATCHED到服务器
  2. 如果我使用user.set({}) woraround,changedAttributes()的返回值为" false"并且所有属性都是PUT到服务器
  3. 如果我在调用user.set("age","123")之前调用save(),那么只有age属性被PATCHED到服务器
  4. 所以结果3是我想要的行为,但是有两个问题:第一个stickit似乎没有使用模型上的set()方法来更新属性,如果它们在html中被更改-形成。其次,如果您使用一个属性调用set(),然后使用另一个属性调用,则changedAttributes()仅返回第二个属性。

    也许我只是监督骨干或backbone.stickit文档中的某些内容,因此我没有得到所需的行为。有关于此的任何想法吗?

1 个答案:

答案 0 :(得分:4)

注意:正如发现的那样,问题与backbone.stickit没有直接关系,更多的是骨干本身。

我自己解决了这个问题,也许这可以帮助那些可能偶然发现这个问题的人:

Backbone仅跟踪未更改的属性,但不跟踪未保存的属性。所以用

model.changedAttributes();

您只会获得自上次

以来已更改的模型属性
model.set("some_attribute","some_value")

最后我偶然发现backbone.trackit这是由backbone.stickit的创建者维护的backbone.js插件。使用此插件,您可以跟踪未保存的属性(自上次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 });
  });

});