Backbone.js:检查数据是否准备好以及数据集是否为空的优雅方法

时间:2012-04-04 17:48:37

标签: javascript backbone.js

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

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

  • 如果一个空的JSON来自于诸如{}的提取,它仍然将BasicDealList.length显示为1而它应该为0因此我被迫通过{{1来检查第一个元素是否为空这非常难看。

以下是代码:

collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]

3 个答案:

答案 0 :(得分:26)

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

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

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

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

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

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

因此传递{}会导致models设置为[{}],这不是您想要的。如果您无法控制服务器,则可以使用自定义{}方法检查.parse(),如果找到则返回[]

答案 1 :(得分:12)

我知道这个问题已经得到解答,但这里有另一种选择。

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”功能使我们能够检查多个获取调用并取得一次成功。

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

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

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

当我们在集合上调用fetch()时,它返回一个jQuery延迟对象。 jQuery延迟对象可以处于3种状态,“挂起”,“拒绝”或“已解决”,一旦我们获得了数据,它就会将延迟对象的状态设置为已解决。

答案 2 :(得分:7)

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

initialize: (objects, options) ->
  @fetched = false
  @listenTo @, 'sync', -> @fetched = true