0

tl;博士

如何使用带有 html 表单的主干.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()稍后使用该方法来获取需要在服务器上打补丁的属性。所以我尝试了我在这里找到的解决方法

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

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

做stickit-bindings

现在我渲染我的视图并调用视图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

或者

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

第二种方法有不同的结果:

  1. 如果我没有使用user.set({})woraround,所有属性都会被修补到服务器
  2. 如果我使用user.set({})woraround 的返回值为changedAttributes()“false”并且所有属性都被 PUT 到服务器
  3. 如果我user.set("age","123")在调用之前调用a save(),那么只有年龄属性被修补到服务器

set()所以结果 3 是我想要的行为,但这有两个问题:首先,如果在 html 表单中更改属性,stickit 似乎没有使用模型上的方法来更新属性。其次,如果您set()使用一个属性调用,然后使用另一个属性调用,则仅返回第二个属性changedAttributes()

也许我只是监督了骨干网或骨干网.stickit 文档中的某些内容,所以我没有得到想要的行为。有什么想法吗?

4

1 回答 1

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 });
  });

});
于 2014-03-21T21:15:21.723 回答