2

次の手順で、モデルの変更された属性のみを保存しようとしています。

        this.model.set("likes", this.model.get("likes") + 1);
        this.model.save();

バックボーンのプロトタイプを次のように拡張します。

var backbone_common_extension = {
    sync: function(method,model,options) {
        options.contentType = 'application/json';
        if (method == 'update') {
            options.data = JSON.stringify(model.changedAttributes() || {});
        }
        console.log(options.data);
        Backbone.sync.call(this, method, model, options);
    }
};

_.extend(Backbone.Model.prototype, backbone_common_extension);

問題は、model.changedAttributes()が常に空であるということです。setメソッドで{silent:true}を渡してみましたが、同じことです。同期する前にバックボーンがchangedAttributes()をクリアしないようにするにはどうすればよいですか?

4

1 に答える 1

5

この種のものに依存するchangedAttributesことはあまりうまく機能しない傾向があります。Backboneには明確に定義されたセット/コミット/保存/ロールバックシステムがないため、changedAttributes予期しないときに空になります。

あなたにとって幸運なことに、それは問題ではありません。あなたにとって不運なことに、あなたのアプローチ全体が間違っているので、それは問題ではありません。サーバーからモデルをロードした後、他のブラウザーから5つのいいねが入った場合はどうなりますか?あなたのアプローチはそれらすべてのいいねを上書きし、データは失われます。

サーバーにいいねの総数を管理させ、モデルは単純に「もう1ついいねがあります」というメッセージを送信し、サーバーに新しい総数で応答させる必要があります。私はそれをもっとこのようにします:

// On the appropriate model...
add_like: function() {
    var _this = this;
    $.ajax({
        type: 'post',
        url: '/some/url/that/increments/the/likes',
        success: function(data) {
            _this.set('likes', data.likes);
        },
        error: function() {
            // Whatever you need...
        }
    });
}

次に、/some/url/...サーバー上のハンドラーは、単純な「1つ追加」の更新をデータベースに送信し、更新されたいいねの数を送り返します。これにより、データベースはデータと同時実行性の問題を管理する責任を負います。データベースはこの種のことに長けていますが、クライアント側のJavaScriptはそれほど得意ではありません。

于 2012-10-29T18:15:21.193 に答える