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

不使用 javascript 发起的位置,而是使用服务器生成的 id,例如 unix 时间戳,并且由于 mu 建议太短,请使用

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 回答
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 回答