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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10016562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 08:28:40  来源:igfitidea点击:

Backbone.js: Elegant way to check if data ready and if the dataset is empty

javascriptbackbone.js

提问by Hellnar

I'm looking for a better solution for two things:

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

  • How can I understand if the data is fetched and ready, I use BasicDealList.on("reset", function(){})to understand if the data is fetched from ajax and parsed and ready to be used but it feels dirty.

  • If an empty JSON comes from fetching such as {}, it still shows BasicDealList.length as 1 while it should be 0 thus I was forced to check if the first element is empty via collection.length == 1 && jQuery.isEmptyObject(BasicDealList.toJSON()[0]which is very ugly.

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

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

Here is the code:

这是代码:

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();

回答by nrabinowitz

If you don't like listening for reset, you can pass a callback directly to .fetch():

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

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

If, later in your app, you want to know whether you've fetched the data already, you could usually just check BasicDealList.length. If you want to avoid making repeated requests for collections that are actually empty on the server, you'll probably need to work out a custom solution, e.g. setting a flag on .fetch():

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

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

As for the empty data issue, you should be returning []from the server instead of {}. Backbone's Collection calls this.add(models, ...)within .reset(), and .add()checks whether the modelsargument is an array; if it's not, it wraps it in one:

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

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

So passing {}will result in modelsset to [{}], which is not what you want. If you can't control the server, you could do the check for {}in a custom .parse()method, returning []if it's found.

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

回答by ericraio

I know this question has already been answered but here is an alternative.

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

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.
});

The key benefit of this is that we are using the "when" function. The "when" function gives us the ability to check multiple fetch calls and do one success.

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

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

Also, if we stored the deferred object into a variable, we can do things like this. The variable will be a flag to let us know that we already loaded 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.

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

回答by Duke

We needed a way to tell if a RelationalModel's relation had been fetched or not. This is our solution (in Coffeescript).

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

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