0

tl;dr

backbone.stickit を html フォームで使用して、サーバーからフェッチされた既存のモデルを変更し、変更された属性 (html フォーム内のユーザー入力によって変更された) のみをサーバーにパッチする方法は?

/tl;dr

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

2 番目のアプローチでは、さまざまな結果が得られます。

  1. 回避策を使用しなかった場合user.set({})、すべての属性がサーバーにパッチされます
  2. 回避策を使用するとuser.set({})、戻り値changedAttributes()は「false」になり、すべての属性がサーバーに PUT されます
  3. を呼び出すuser.set("age","123")前に を呼び出すとsave()、 age 属性のみがサーバーにパッチされます

set()したがって、結果 3 は私の望ましい動作ですが、これには 2 つの問題があります。最初の stickit は、html フォーム内で属性が変更された場合、属性を更新するためにモデルのメソッドを使用していないようです。次に、ある属性を指定して呼び出しset()、その後別の属性を指定すると、2 番目の属性のみが によって返されchangedAttributes()ます。

backbone または backbone.stickit ドキュメントで何かを監視しただけかもしれません。それについてのアイデアはありますか?

4

1 に答える 1

4

注:問題が backbone.stickit に直接関係していないことがわかったので、backbone 自体にもっと関係があります。

この問題を自分で解決しました。これは、この質問に出くわす可能性のある人を助けるかもしれません:

バックボーンは変更されていない属性のみを追跡しますが、保存されていない属性は追跡しません。だから

model.changedAttributes();

前回から変更されたモデルの属性のみを取得します

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

最後に、backbone.stickit の作成者によって管理されているbackbone.jsプラグインである backbone.trackit に出くわしました。このプラグインを使用すると、保存されていない属性 (最後の から変更されたすべての属性) を追跡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 に答える