17

我有两套收藏。一个用于类别,另一个用于项目。我需要等待类别完成获取所有内容,以便为要获取的项目设置类别。

另外,我每次单击一个类别时都必须重新获取一个新的项目集合,因为每次单击一个类别时都会进行分页,它不会刷新或重新获取集合,因此分页代码会弄乱错误的集合. 有任何想法吗?

this.categoryCollection = new CategoryCollection();
this.categoryCollection.fetch();

this.itemCollection = new ItemCollection();
this.itemCollection.fetch();
4

6 回答 6

57

刚遇到类似的情况。我最终将 jquery.ajax 参数传递给 fetch() 调用。您可以使第一次获取同步。从骨干文档

jQuery.ajax 选项也可以直接作为 fetch 选项传递

您的代码可以简化为:

this.categoryCollection.fetch({async:false});
this.itemCollection.fetch();
于 2012-08-26T21:01:44.557 回答
15

一种快速的方法是将回调传递给fetch()调用第二个调用的第一个调用。fetch()接受一个options支持success(and error) 回调的对象。

var self = this;
this.categoryCollection = new CategoryCollection();
this.categoryCollection.fetch({
    success: function () {
        self.itemCollection = new ItemCollection();
        self.itemCollection.fetch();
    }
});

不是最优雅的,但它有效。你可能可以用 deferreds 做一些有创意的事情,因为返回由发生的调用fetch()创建的 jQuery deferred 。$.ajax

对于分页问题,​​如果不查看分页代码在做什么,就很难判断。您将不得不自己滚动分页内容,因为 Backbone 本身不支持它。我可能要做的是为正在查询的页面标准创建一个新的集合,并可能创建一个我可以点击的支持分页的服务器操作(将集合映射url到分页服务器操作)。不过,我并没有为此考虑太多。

于 2012-05-08T01:58:16.310 回答
2

由于那里的答案,我不得不对这个线程做出反应。

这是做这件事的唯一方法!!!

this.categoryCollection = new CategoryCollection();
this.itemCollection = new ItemCollection();

var d1 = this.categoryCollection.fetch();
var d2 = this.itemCollection.fetch();

jQuery.when(d1, d2).done(function () {
     // moment when both collections are populated
     alert('YOUR COLLECTIONS ARE LOADED :)'); 
});

通过这样做,您可以同时获取两个集合,并且当两者都准备好时您可以拥有事件。因此,您不必等待完成加载第一个集合以获取其他集合,您不会进行 ajax 调用同步等,您可以在其他答案中看到!

这是有关延迟对象的文档。

注意:在这个例子中,当一个或多个延迟对象失败时,它不被覆盖。如果您还想涵盖这种情况,.done则必须在此示例中添加.fail回调.when并添加error将标记失败 d1 或 d2 的处理程序。

于 2017-04-15T15:21:25.667 回答
0

我正在使用 RelationalModel 并创建了一个排队获取,它仅在加载完成时调用“更改”事件:

var MySuperClass = Backbone.RelationalModel.extend({
    //...

    _fetchQueue : [],

    fetchQueueingChange : function(name){
        //Add property to the queue
        this._fetchQueue.push(name);
        var me = this;

        //On fetch finished, remove it
        var oncomplete = function(model, response){
            //From _fetchQueue remove 'name'
            var i = me._fetchQueue.indexOf(name);
            me._fetchQueue.splice(i, 1);

            //If done, trigger change
            if (me._fetchQueue.length == 0){
                me.trigger('change');
            }
        };

        this.get(name).fetch({
            success: oncomplete, 
            error : oncomplete
        });
    },

    //...


});

该类将调用:

this.fetchQueueingChange('categories');
this.fetchQueueingChange('items');

我希望你能改进这一点,它对我很有效。

于 2012-05-08T02:27:32.060 回答
0

我今天遇到了同样的问题,并想出了一个解决方案:

var self = this;
this.collection = new WineCollection();
this.collection.url = ApiConfig.winetards.getWineList;
this.collection.on("reset", function(){self.render()});
this.collection.fetch({reset: true});

现在,当对集合的提取完成时,会触发“重置”,并在“重置”时调用视图的 render() 方法。

使用{async: false}不是处理 Backbone 的 fetch() 的理想方式。

于 2014-12-17T11:56:51.440 回答
-10

只需将 jQuery 设置为同步

$.ajaxSetup({
  async: false
});   
this.categoryCollection.fetch();
this.itemCollection.fetch();
$.ajaxSetup({
  async: true
});

我猜这是最简单的解决方案。当然,在这些 fetch 运行时启动新请求也将以同步方式启动,这可能是您不喜欢的。

于 2012-05-08T09:19:13.177 回答