Skip to content

Instantly share code, notes, and snippets.

@junosuarez
Created September 23, 2012 02:46
Show Gist options
  • Save junosuarez/3768642 to your computer and use it in GitHub Desktop.
Save junosuarez/3768642 to your computer and use it in GitHub Desktop.
Async Collection
/*global define:false */
define(['backbone','underscore','deferred'], function (B, _, flow) {
/**
* @constructor
*/
var AsyncCollection = B.Collection.extend({
initialize: function () {
// if the initialize function is overriden in an
// extended class of AsyncCollection, ensure
// that `this` for `getAsync`, `has` and `hasAll` is
// still bound to the collection.
_.bindAll(this);
},
getAsync: getAsync,
hasAll: hasAll,
has: has
});
/**
* Useful helper function for determining if a set of models
* is in the collection by ids
* @param {array.<number>} ids
* @return {Boolean} true if Collection contains all `ids`
*/
function hasAll (ids) {
var index = this._byId;
return _.all(ids, function (id) {
// check Collection id index
return _.has(index, id);
});
}
function has (id) {
return _.has(this._byId, id);
}
/**
* Get a promise for a model in a Backbone collection that
* is fulfilled when the model is added.
* Mixin to a Backbone collection.
*
* @param {Backbone.Collection} collection
* @param {string or number} id
* @return {promise.<Backbone.Model}
*/
function getAsync (id) {
var dfd = new flow.Deferred(),
collection = this;
// check if we can resolve the promise immediately,
// otherwise set up a listener to resolve it later
if (!tryResolve()) {
var handler = function () {
if (tryResolve()) {
// promise was resolved, unregister handler
collection.off('add reset', handler);
}
};
// listen for changes to the collection
collection.on('add reset', handler);
}
function tryResolve (){
// check if the model is in the collection
if (_.has(collection._byId, id)) {
// get requested model and resolve the promise
dfd.resolve(collection.get(id));
return true;
} else {
return false;
}
}
return dfd.promise();
}
return AsyncCollection;
});
@junosuarez
Copy link
Author

Note: the deferred dependency is using (underscore.deferred)[https://github.com/jden/underscore.deferred], but could easily be substituted for jQuery.Deferred, on which it is based.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment