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

Hel*_*nar 14 javascript backbone.js

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

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

  • 如果一个空的JSON来自提取,例如{},它仍然显示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();
Run Code Online (Sandbox Code Playgroud)

nra*_*itz 26

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

BasicDealList.fetch({
    success: function(collection, response){
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

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

BasicDealList.fetch({
    success: function(collection, response){
        BasicDealList.fetched = true;
        // ...
    }
});
Run Code Online (Sandbox Code Playgroud)

至于空数据问题,你应该[]从服务器返回而不是{}.骨干收集调用this.add(models, ...).reset(),并.add()检查是否models参数是一个数组; 如果不是,它将它包装成一个:

models = _.isArray(models) ? models.slice() : [models];
Run Code Online (Sandbox Code Playgroud)

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


eri*_*aio 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.
});
Run Code Online (Sandbox Code Playgroud)

这样做的主要好处是我们正在使用"when"功能."when"功能使我们能够检查多个获取调用并取得一次成功.

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

此外,如果我们将延迟对象存储到变量中,我们可以执行此类操作.变量将是一个标志,告诉我们已经加载了数据.

if (deferred.state() === "resolved") {
    // do stuff when we have the data.
}
Run Code Online (Sandbox Code Playgroud)

当我们在集合上调用fetch()时,它返回一个jQuery延迟对象.jQuery延迟对象可以处于3种状态,"挂起","拒绝"或"已解决",一旦我们拥有数据,它将设置要解析的延迟对象的状态.


Duk*_*uke 7

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

initialize: (objects, options) ->
  @fetched = false
  @listenTo @, 'sync', -> @fetched = true
Run Code Online (Sandbox Code Playgroud)