backbone:在重置集合之前发出ajax调用

时间:2012-08-14 06:14:20

标签: ajax collections asynchronous backbone.js

现在我有一个取值的集合,然后重新生成附加到重置事件的每个视图

问题是我还必须发出另一个查询来获取检索到的记录总数,并且只有在完成ajax调用之后才应该触发重置事件

使用一些代码更清楚:

fetch: function() {
  options = { data: this.getParams() };
  this.fetch_total();
  return Backbone.Collection.prototype.fetch.call(this, options);
},

fetch_total: function() {
  var that = this;
  var options = { 
    url: this.url + '/count',
    data: this.getParams(),
    contentType: 'application/json',
    success: function(resp, status, xhr) {
      that.total = parseInt(resp);
      return true;
    }
  };
  return $.ajax(options);
}

正如你所看到的,我必须发出一个get to localhost / myentity / count来获取实体的数量......

问题是我需要在刷新视图之前更新collection.total变量,这意味着我需要在刷新所有视图之前完成请求,GET到localhost / myentity和localhost / myentity / count ...

任何想法我怎么能实现它?

3 个答案:

答案 0 :(得分:2)

如果您选择的$是jQuery> 1.5,则可以利用deferred object在两个调用完成时手动触发重置事件。与您的答案类似,但更具可读性且没有链接呼叫:

fetch: function() {
  options = {silent: true, data: this.getParams()};
  var _this = this;
  var dfd_total = this.fetch_total();
  var dfd_fetch = Backbone.Collection.prototype.fetch.call(this, options);

  return  $.when(dfd_total, dfd_fetch).then(function() {
        _this.trigger('reset', _this);
  })
},

fetch_total: function() {
    // what you have in your question
}

还有一个模拟这些调用的小提琴http://jsfiddle.net/rkzLn/

当然,在一次获取中返回结果和总数可能会更有效,但我想这不是一种选择。

答案 1 :(得分:1)

我认为@ nikoshr的答案很好,因此您无需修改​​API。如果您认为要减少对服务器的调用,请考虑从该端点返回具有分页信息的对象。

{
  count: 1243,
  page: 3,
  per_page: 10,
  results: [
    ...
  ]
}

然后覆盖集合的解析功能

parse: function(res) {
  this.count = res.count;
  this.page = res.page;
  this.per_page = res.per_page;
  // return the collection
  return res.results;
}

<强>资源

答案 2 :(得分:0)

我想我找到了办法。我所做的是默默地触发提取调用,而不触发'重置'事件

在回调中,我发出了总数的获取(GET到localhost / myentity / count)

从总回调中,我终于触发了重置事件

代码中的

是这样的:

fetch: function() {
  var that = this;
  options = {
    // will manually trigger reset event after fetching the total
    silent: true,       
    data: this.getParams(),
    success: function(collection, resp) {
      that.fetch_total();
    } 
  };
  return Backbone.Collection.prototype.fetch.call(this, options);
},

fetch_total: function() {
  var that = this;
  var options = { 
    url: this.url + '/count',
    data: this.getParams(),
    contentType: 'application/json',
    success: function(resp, status, xhr) {
      that.total = parseInt(resp);
      // manually trigger reset after fetching total
      that.trigger('reset', that);    
      return true;
    }
  };
  return $.ajax(options);
}

这是我的第一次尝试,我想知道是否有更简单的方法