web-dev-qa-db-fra.com

Attendez que la collection récupère tout dans le réseau principal

J'ai deux séries de collections. L'une concerne les catégories et l'autre les articles. Je dois attendre que les catégories aient fini de tout récupérer pour que je puisse définir la catégorie des éléments à récupérer. 

De plus, chaque fois que je clique sur une catégorie, je dois extraire à nouveau une nouvelle collection d'objets car une pagination est activée à chaque fois que je clique sur une catégorie pour laquelle elle n'actualise pas ou ne récupère pas la collection, de sorte que le code de pagination gâche la mauvaise collection. . Des idées?

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

this.itemCollection = new ItemCollection();
this.itemCollection.fetch();
16
jongbanaag

Un moyen rapide serait simplement de passer un rappel au premier appel fetch() qui appelle le second. fetch() prend un objet options qui prend en charge un rappel success (et error).

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

Pas le plus élégant, mais ça marche. Vous pourriez probablement faire des créations avec des tâches différées puisque fetch() renvoie le jQuery différé créé par l'appel $.ajax qui se produit.

Pour le problème de la pagination, il est difficile de dire sans voir ce que fait votre code de pagination. Vous allez devoir vous charger vous-même de la pagination, car Backbone ne le supporte pas nativement. Ce que je ferais probablement serait de créer une nouvelle collection pour les critères de page interrogés et probablement de créer une action de serveur susceptible de prendre en charge la pagination (mappage de la variable url de la collection avec l'action de serveur paginé). Je n'y ai pas réfléchi longuement.

15
Rob Hruska

Juste couru dans une situation similaire. J'ai fini par passer les paramètres jquery.ajax à l'appel fetch (). Vous pouvez faire la première extraction synchrone. À partir du dorsal docs

les options jQuery.ajax peuvent également être passées directement en tant qu'options d'extraction

Votre code pourrait être simplifié à quelque chose comme:

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

J'ai dû réagir à ce fil à cause des réponses fournies.

C'est la seule façon de faire ce droit !!!

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

Ce faisant, vous récupérez les deux collections en même temps et vous pouvez avoir un événement lorsque les deux sont prêtes. Donc, vous n’attendez pas pour finir de charger les premières collections afin d’en récupérer d’autres, vous ne faites pas la synchronisation d’appels ajax, etc. que vous pouvez voir dans d’autres réponses!

Voici un doc sur Objets différés .

Remarque: dans cet exemple, lorsqu'un ou plusieurs objets différés échouent, ils ne sont pas couverts. Si vous souhaitez couvrir ce cas également à côté de .done, vous devrez ajouter .fail callback sur .when et ajouter également le gestionnaire error qui marquera l'échec de d1 ou d2 dans cet exemple.

3
Nikola Loncar

J'utilise RelationalModel et j'ai créé une extraction en file d'attente, qui appelle uniquement l'événement 'change' une fois le chargement terminé:

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

    //...


});

La classe appellerait:

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

J'espère que vous pourrez améliorer cela, cela a bien fonctionné pour moi.

0
miguelr

Je me suis retrouvé avec le même problème aujourd'hui et j'ai trouvé une solution à cela:

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

Maintenant, lorsque l'extraction sur la collection est terminée, une "réinitialisation" est déclenchée et, après "réinitialisation", appelez la méthode render () pour la vue. 

Utiliser {async: false} n'est pas le moyen idéal de gérer la fonction fetch () de Backbone. 

0
Ashwin kumar