I'd like to run view.render() if both collectionA and collectionB have fired 'sync' event. Something like this.
collectionA = new CollectionA();
collectionB = new CollectionB();
view.listenTo([collectionA, collectionB], 'sync', view.render);
collectionA.fetch(); // do not call view.render yet.
collectionB.fetch(): // call view.render after fetch.
I know there is a way to use $.when() or _.after() like this answers. How to synchronize multiple Backbone.js fetches?
But I think these are not event-driven way. Is there any event-driven way on Backbone.js?
You can use a combination of underscore's after
method to only execute the callback when it's been called a number of times, and Backbone.Events.once
to ensure that you don't trigger the handler prematurely, if one of the collections fires two sync
events, instead of one from each:
var callback = _.after(2, view.render);
collectionA.once('sync', callback, view);
collectionB.once('sync', callback, view);
Or you can wrap the logic into a utility function, so you can use it with a variable number of event sources:
function onceAll(eventSources, eventName, handler, context) {
handler = _.after(eventSources.length, handler);
context = context || this;
_.each(eventSources, function(source) {
source.once(eventName, handler, context);
});
}
Usage:
onceAll([collectionA, collectionB], 'sync', view.render, view);
/Code samples not tested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With