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();
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.
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();
J'ai dû réagir à ce fil à cause des réponses fournies.
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.
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.
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.