Подождите, пока коллекция заберет все в магистрали - программирование
Подтвердить что ты не робот

Подождите, пока коллекция заберет все в магистрали

У меня есть два набора коллекций. Один из них относится к категориям, а другой относится к элементам. Мне пришлось ждать, пока категории закончат выборку для меня, чтобы установить категорию для элементов, которые будут выбраны.

Также каждый раз, когда я нажимаю категорию, я должен повторно извлекать новую коллекцию элементов, потому что у меня есть разбиение на страницы, которое происходит каждый раз, когда я нажимаю на категорию, в которой она не обновляется или не возвращается к коллекции, так что код разбивки на страницы возится с неправильная коллекция. Любые идеи?

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

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

Ответ 1

Одним быстрым способом было бы просто передать обратный вызов в первый вызов fetch(), который вызывает второй. fetch() принимает объект options, который поддерживает обратный вызов successerror).

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

Не самый элегантный, но он работает. Возможно, вы могли бы сделать некоторые творческие материалы с отсрочками, так как fetch() возвращает отложенный jQuery, который создается созданным вызовом $.ajax, который происходит.

В отношении вопроса о разбиении на страницы трудно сказать, не видя, что делает ваш код разбивки на страницы. Вам придется вручную перетаскивать нумерацию, так как Backbone не поддерживает ее. То, что я, вероятно, сделаю, это создать новую коллекцию для критериев страницы, которые запрашиваются, и, возможно, создать действие сервера, которое я мог бы нанести, что будет поддерживать разбиение на страницы (отображение коллекции url на действие с разбивкой по страницам). Тем не менее, я не вникаю в это.

Ответ 2

Просто столкнулся с подобной ситуацией. Я закончил передачу параметров jquery.ajax вызову fetch(). Вы можете сделать первую выборку синхронной. Из dbc:

Параметры jQuery.ajax также могут передаваться непосредственно в качестве параметров выборки

Ваш код можно упростить, например:

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

Ответ 3

Мне пришлось отреагировать на эту тему из-за ответов там.

Это ТОЛЬКО ПУТЬ ДЕЛАТЬ ЭТОТ ПРАВО!!!

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 в этом примере.

Ответ 4

Я использую RelationalModel, и я создал выборочную выборку, которая только вызывает событие "change" при загрузке:

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

Надеюсь, вы сможете улучшить это, это сработало для меня.

Ответ 5

Сегодня я столкнулся с той же проблемой и понял, как это решить:

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

Теперь, когда выборка в коллекции завершена, запускается "reset", а после "reset" вызывает метод render() для представления.

Использование {async: false} не является идеальным способом работы с Backbone fetch().

Ответ 6

просто установите jQuery для синхронного

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

Это самое простое решение, я думаю. Конечно, запуск новых запросов при запуске этих запусков также будет запущен как синхронный, что может быть что-то вам не нравится.