6

Web アプリにドラッグ アンド ドロップ機能があります。ユーザーがドラッグ アンド ドロップ後にマウスを離すと、モデルで Backbone の save() メソッドを使用して、オブジェクトの位置がサーバーに保存されます。サーバーが応答すると、返されたプロパティを使用してモデルで set() をトリガーします。ただし、サーバーがリクエストを処理している間に、ユーザーがオブジェクトを別の位置にドラッグしている可能性があります。これにより、サーバーからの応答がブラウザ内のオブジェクトの設定を上書きするため、問題が発生します。

save() の後にサーバーからの応答を取得した後、Backbone が set() を実行するのを防ぐ方法はありますか?

4

10 に答える 10

3

以前にシステムを実行しているときに同様のユースケースがありましたが、それはより面倒だったため、モデルset()関数を実際にオーバーライドする必要がありました。ただし、この場合、比較的簡単な方法がいくつかあります。

モデルのparse()関数をオーバーライドできます。abort()または、呼び出しによって返された jqXHR オブジェクトでを呼び出すことができますsave()

http://api.jquery.com/jQuery.ajax/#jqXHR

于 2013-09-11T16:09:22.140 に答える
2

「待機」オプションを調べます。デフォルトでは false に設定する必要があります。これは、save() を呼び出した直後にモデル フィールドを設定する必要があることを意味します。{wait:true} を設定して、更新されたモデル フィールド値を設定する前にバックボーンがサーバーの応答を待機するようにすることができます。

説明された動作から、アプリケーションで待機オプションが true に設定されているようです。

詳細: http://backbonejs.org/#Model-save

覚えておくべきもう1つの重要なことは、バックボーンは、呼び出されたWebサービスから返す更新されたフィールドのサブセットのみを設定するため、何も返さない場合は何も設定されないということです.

于 2013-08-21T17:31:16.887 に答える
2

Model.save実際に設定する前にModel.parse、同じ引数で受信したデータを呼び出します。options

サーバーが返すものを破棄できることを示すModel.saveカスタム フラグ (たとえばposition: true) を使用して呼び出すことができます。Model.parse

たとえば、あなたの座標xy

var M = Backbone.Model.extend({
    parse: function(data, options)  {
        if (options && options.position)
            data = _.omit(data, 'x', 'y');

        return data;
    }
});

var m = new M();
m.save({x: 10, y:10}, {position: true});
m.save({x: 20, y:20}, {position: true});

そしてデモhttp://jsfiddle.net/nikoshr/YwC7q/

于 2013-09-18T08:43:13.450 に答える
0

ajax リクエストが実行されるまで UI をフリーズするアプローチを使用しました。保存前とサーバーからの応答の受信後にトリガーされる 2 つの追加イベントのフリーズ/フリーズ解除をモデルに追加しました。

于 2013-09-12T19:52:57.487 に答える
0

バックボーンの保存成功のコールバック:

  options.success = function(resp, status, xhr) {
    done = true;
    var serverAttrs = model.parse(resp, xhr);
    if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
    if (!model.set(serverAttrs, options)) return false;
    if (success) success(model, resp, options);
    model.trigger('sync', model, resp, options);
  };

したがって、トリガー「同期」が呼び出される前、およびユーザー成功関数が呼び出される前に、常に set を呼び出します。バックボーンが設定を行うのを防ぐ方法はありませんが、問題を解決する方法があります。次のように、モデルの「set」関数をオーバーライドできます。

set: function() {
  if (this.skipSetOperation()) return false;
  return Backbone.Model.prototype.set.apply(this, arguments);
},

skipSetOperation: function() {
  //this function should return stage - can model set attributes in this moment or not
}

それが役に立てば幸い。

于 2013-09-18T08:29:52.747 に答える
0

現在、次のソリューションを使用しています。

モデルのデフォルトのパース メソッドをオーバーライドします。

Backbone.Model.prototype.parse = function(resp, options) {
    if(options.parse)
        return resp;
};

これで、プロパティ 'parse' を false に設定して save メソッドを使用して、ajax 応答が現在の値をオーバーライドするのを防ぐことができます。

MyModel.save({}, { parse: false });
于 2013-10-16T08:49:48.950 に答える
0

「.sync()」メソッドをオーバーライドしてみてください。Backbone.save() は、渡した成功コールバックをオーバーライドした後、Backbone.sync() に委譲します。モデルの更新はここから行われます。

Backbone.save() メソッドのソースから:

var success = options.success;
  options.success = function(resp) {
    // Ensure attributes are restored during synchronous saves.
    model.attributes = attributes;
    var serverAttrs = model.parse(resp, options);
    if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
    if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
      return false;
    }
    if (success) success(model, resp, options);
    model.trigger('sync', model, resp, options);
  };
  wrapError(this, options);

  method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
  if (method === 'patch') options.attrs = attrs;
  xhr = this.sync(method, this, options);

「.save()」を呼び出すときにカスタム オプションを渡し、そのオプションを探して、「.sync()」で options.success コールバックをオーバーライドできます。もしかして、こういうこと?

MyModel = Backbone.Model.extend({
    sync: function (method, context, options) {
        if (options.skipUpdateOnResponse) {
            options.success = myCusomSuccessFunction;
        }
    }
});

myModel = new MyModel();

myModel.save({...}, {skipUpdateOnResponse: true})
于 2013-09-16T01:23:27.443 に答える
-1

保存用に別の関数を作成し、保存を使用する代わりに関数を使用します。

モデルで:

var myModel = Backbone.Model.extend({
     savePosition: function(){
           var model = this;    
           $.ajax({
                type : "POST",
                cache: false,
                dataType : 'json',
                contentType : 'application/json',
                data:JSON.stringify(data),
                url : "urlToSave",
                success:function(responseText,statusText){
                    model.trigger('saved',responseText);
                },
                error : function(error, dataObj, xhr) {
                                        alert('Error');
                }
      });    
     }
}

ここでは、保存されたメソッドをバインドし、保存後にメソッドをトリガーします。

this.model.on('saved',function(){
   // do call back stuff
});
this.model.savePosition({data:{...}});
于 2013-09-12T09:53:01.680 に答える