Skip to content

Instantly share code, notes, and snippets.

@aaronj1335
Last active August 29, 2015 13:57
Show Gist options
  • Select an option

  • Save aaronj1335/9769565 to your computer and use it in GitHub Desktop.

Select an option

Save aaronj1335/9769565 to your computer and use it in GitHub Desktop.
waterfall data layer
define([
'underscore',
'knockout'
], function(_, ko) {
function Collection() {
}
Collection.prototype.init = function() {
this._instances = ko.observableArray();
};
// to be overridden:
// - Collection.prototype.url
// - Collection.prototype.create
// - Collection.prototype.update
Collection.prototype._dedupe = function(item) {
var existing = this.byId(item.id);
if (!existing) {
existing = this.create(item);
this._instances.push(existing);
} else {
this.update(existing, item);
}
return existing;
};
Collection.prototype.byId = function(id) {
return _.find(this._instances(), function(instance) {
return instance.id() === id;
});
};
Collection.prototype.fetch = function(params) {
// the specific thing we're using for the ajax request should maybe be
// abstracted
return $.ajax(_.extend({
url: this.url
}, params))
.then(function(result) {
result.forEach(this._dedupe.bind(this));
return result;
});
};
Collection.prototype.fetchOne = function(id, params) {
return $.ajax(_.extend({
url: this._url + '/' + id
}, params))
.then(function(item) {
return this._dedupe(item);
});
};
// also need to figure out saving and deleting. two options:
// - add them as methods to Collection.prototype (uglier)
// - add them as methods to the items in resource._instances, but then we
// need a way of updating that list when an item is saved or deleted
return Collection;
});
define([
'ko',
'waterfall',
'collection'
], function(ko, waterfall, Collection) {
var instance;
function MetadataCollection() {
this.init();
}
MetadataCollection.prototype = new Collection();
MetadataCollection.prototype.url = waterfall.metadata.url;
// this is where things get weird. we probably want to return an instance of
// something w/ a 'save' and 'delete' method, but those instances need some
// way of notifying the Collection instance when they're deleted or saved for
// the first time so the Collection can update its _instances OA accordingly
//
// so basically like a Record class
MetadataCollection.prototype.create = function(item) {
return {
id: ko.observable(item.id),
name: ko.observable(item.name),
multiValue: ko.observable(item.multiValue),
format: ko.observable(item.format)
};
};
MetadataCollection.prototype.update = function(existing, item) {
existing.id(item.id);
existing.name(item.name);
existing.multiValue(item.multiValue);
existing.format(item.format);
};
// use an accessor function, since we'll usually just want a single shared
// app-wide Collection of MetadataCollection, but we want to be able to reset
// that instance for stuff like unit testing
//
// the "singleton pattern", or "object manager factory get instance function"
function accessor() {
return instance? instance : instance = new MetadataCollection();
}
accessor.MetadataCollection = MetadataCollection;
accessor.reset = function() {
instance = null;
};
return accessor;
});
@evanrmurphy
Copy link

Now for the fun part: what should we name this little library we're developing? 😄 Knockout Data? Boxing Gloves? (Because you wouldn't want to knock someone out without boxing gloves!)

@evanrmurphy
Copy link

Started a branch for this called "data-layer" in WaterfallEngineering/frontend.

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