3

ファイルのリストの特定のインデックスで(FormDataを使用して)非同期的にファイルをアップロードしています:

files.create({position: index + 1 }, {at: index}); // files is Backbone.Collection

次に、サーバーはアップロードを保存し、特定の位置の後にファイルの位置をシフトして、新しく挿入されたファイルの場所を解放します。

次に、クライアントでイベントの追加をリッスンし、オプションのインデックスを使用してファイルビューを挿入します。

files.on("add", function(model, collection, options) {
    // insert file view at options.index position
})

positionコレクション内のすべてのモデルの属性も更新します。

files.on("add remove", function(){ 
  this.each(function(m, index) {
    m.set({position: index + 1});
  })
});

問題は、同じインデックス位置に一度に多くのファイルをアップロードすると、ファイル ビューが間違った順序でリストに追加されることです。

positionバックボーン コレクションでファイル モデルの正しい順序と属性を確保するにはどうすればよいですか?

4

2 に答える 2

0

ajax リクエストをキューに入れる collection.create をオーバーライドできました。そのために、この回答のコードを使用しました。

var Documents = Backbone.Collection.extend({

  model: Document,

  url: "/a/documents",

  initialize: function() {
    this.on("add remove", this.updatePositions, this);
    this.ajaxQueue = $({});
  },

  updatePositions: function(model, collection, options) {
    this.each(function(m, index) {
      m.set({position: index + 1});
    })
  },

  create: function(model, options) {
    var jqXHR
      , dfd = $.Deferred()
      , promise = dfd.promise()
      , coll = this;

    // queue our ajax request
    this.ajaxQueue.queue(doRequest);

    // add the abort method
    promise.abort = function(statusText) {
      // Proxy abort to the jqXHR if it is active
      if (jqXHR) {
        return jqXHR.abort(statusText);
      }

      // If there wasn't already a jqXHR we need to remove from queue
      var queue = this.ajaxQueue.queue()
        , index = $.inArray(doRequest, queue);

      if (index > -1) {
        queue.splice(index, 1);
      }

      // Reject the deferred
      dfd.rejectWith(options.context || options,
                     [promise, statusText, ""]);

      return promise;
    };

    // Run the actual collection.create
    function doRequest(next) {
      options = options ? _.clone(options) : {};
      model = coll._prepareModel(model, options);
      if (!model) return false;
      if (!options.wait) coll.add(model, options);
      var success = options.success;
      options.success = function(nextModel, resp, xhr) {
        if (options.wait) coll.add(nextModel, options);
        if (success) {
          success(nextModel, resp);
        } else {
          nextModel.trigger('sync', model, resp, options);
        }
      };
      jqXHR = model.save(null, options)
        .done(dfd.resolve)
        .fail(dfd.reject)
        .then(next, next);
    };

    return promise;
  }

});
于 2012-11-29T09:20:51.430 に答える
0

javascript で生成された位置を使用する代わりに、UNIX タイムスタンプなどのサーバーで生成された ID を使用します。

comparitor: function() { 
    return -this.timestamp // negative ensures latest items show up on top, and olders at the bottom 
}

より具体的な並べ替えが必要な場合は、いつでもより細かいマイクロタイムに移動するか、単にサーバー側で増分 ID を生成できます。

于 2012-11-29T06:32:23.027 に答える