15

我正在为两件事寻找更好的解决方案:

  • 我如何了解数据是否已获取并准备好,我BasicDealList.on("reset", function(){})用来了解数据是否从 ajax 获取并解析并准备好使用但感觉很脏。

  • 如果一个空的 JSON 来自于 fetch {},它仍然显示 BasicDealList.length 为 1 而它应该是 0 因此我不得不检查第一个元素是否为空,collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]这非常难看。

这是代码:

BasicDeal = Backbone.Model.extend();    
BasicDealCollection = Backbone.Collection.extend({
    model: BasicDeal,
    url: '/some/ajax/url/',
});
BasicDealList = new BasicDealCollection();

BasicDealList.on("reset", function(collection, response){
    isEmpty = collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]);
    if (isEmpty){
    // render no deal found html
    }
    else{ 
    // render list of deals
    }
}
BasicDealList.fetch();
4

3 回答 3

27

如果您不喜欢听reset,可以直接将回调传递给.fetch()

BasicDealList.fetch({
    success: function(collection, response){
        // ...
    }
});

如果稍后在您的应用程序中,您想知道您是否已经获取数据,您通常只需检查BasicDealList.length. 如果您想避免重复请求服务器上实际上为空的集合,您可能需要制定一个自定义解决方案,例如设置一个标志.fetch()

BasicDealList.fetch({
    success: function(collection, response){
        BasicDealList.fetched = true;
        // ...
    }
});

至于空数据问题,您应该[]从服务器返回而不是{}. Backbone 的 Collection 调用this.add(models, ...)inside .reset(),并.add()检查models参数是否为数组;如果不是,则将其包装在一个中:

models = _.isArray(models) ? models.slice() : [models];

所以传递{}将导致models设置为[{}],这不是你想要的。如果您无法控制服务器,您可以{}在自定义.parse()方法中进行检查,[]如果找到则返回。

于 2012-04-04T18:05:39.153 回答
13

我知道这个问题已经得到回答,但这里有一个替代方案。

BasicDealCollection = Backbone.Collection.extend({
    model: BasicDeal,
    url: '/some/ajax/url/',
});

myCollection = new BasicDealCollection()
deferred = myCollection.fetch()

$.when(deferred).then(function() {
  // do stuff when we have the data.
});

这样做的主要好处是我们使用了“when”函数。“when”函数使我们能够检查多个 fetch 调用并成功执行一次。

$.when(deferredOne, deferredTwo, deferredThree).then(function() {
  // do stuff when we have the data.
});

此外,如果我们将延迟对象存储到一个变量中,我们可以做这样的事情。该变量将是一个标志,让我们知道我们已经加载了数据。

if (deferred.state() === "resolved") {
    // do stuff when we have the data.
}

When we call fetch() on a collection it returns a jQuery deferred object. A jQuery deferred object can be in 3 states, "pending", "rejected" or "resolved" and once we have the data, it will set the state of the deferred object to resolved.

于 2014-02-20T02:40:38.510 回答
7

我们需要一种方法来判断是否已获取 RelationalModel 的关系。这是我们的解决方案(在 Coffeescript 中)。

initialize: (objects, options) ->
  @fetched = false
  @listenTo @, 'sync', -> @fetched = true
于 2013-09-10T23:42:25.500 回答