Last active
January 2, 2016 18:59
-
-
Save justinwinslow/8347017 to your computer and use it in GitHub Desktop.
Angular $resource abstraction for Backbone collection-like interactions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
TODO | |
[ ] Returns return a $q promise or the $resource return. Need to mimic the | |
$resource return for all returns | |
[ ] Extend Collection with underscore methods | |
*/ | |
angular.module('ngCollection', ['ngResource']) | |
.factory('$collection', ['$resource', '$q', function($resource, $q){ | |
// Collection constructor | |
var Collection = function(url, defaultParams){ | |
// Remove leading slash if provided | |
url = (url[0] == '/') ? url.slice(1) : url; | |
// Instantiate resource | |
var resource = $resource('/' + url + '/:id', defaultParams, { | |
// Add PUT method since it's not available by default | |
update: { | |
method: 'PUT' | |
} | |
}); | |
// Store models for manipulation and display | |
this.models = []; | |
// Expose resource promise and resolved | |
this.$resolved = true; | |
this.$promise = null; | |
// Expose method for querying collection of models | |
this.query = function(params){ | |
params = params || {}; | |
var that = this; | |
var query = resource.query(params); | |
// Update exposed promise and resolution indication | |
this.$resolved = false; | |
this.$promise = query.$promise; | |
// Update models | |
this.$promise.then(function(response){ | |
// Loop through models | |
_.each(response, function(model){ | |
var existingModel = _.find(that.models, {id: model.id}); | |
if (existingModel) { | |
// Update existing model | |
_.extend(existingModel, model); | |
} else { | |
// or push new model | |
that.models.push(model); | |
} | |
}); | |
that.$resolved = true; | |
}); | |
return query; | |
}; | |
// Get an individual model | |
this.get = function(params){ | |
// If a string is passed, assume it's an id | |
params = (typeof params == 'string') ? {id: params} : params; | |
var get = resource.get(params); | |
console.log(get); | |
return get; | |
}; | |
// Add model to collection without saving it | |
this.add = this.push = function(model){ | |
var defer = $q.defer(); | |
var add = defer.promise; | |
this.models.push(model); | |
// Resolve the defer immediately since the push isn't async | |
defer.resolve(model); | |
return add; | |
}; | |
// Save a new model | |
this.save = function(model){ | |
var that = this; | |
var save; | |
if (model.id) { | |
save = resource.update({id: model.id}, model); | |
_.extend(_.find(this.models, {id: model.id}), model); | |
} else { | |
save = resource.save(model); | |
save.$promise.then(function(model){ | |
// Add model to collection | |
that.models.push(model); | |
}); | |
} | |
return save; | |
}; | |
// Delete existing model | |
this.remove = this.del = function(model){ | |
var remove; | |
// If the model has an id we need to del it from the database | |
if (model.id) { | |
remove = resource.remove({id: model.id}); | |
} else { | |
var defer = $q.defer(); | |
remove = defer.promise; | |
// Resolve defer immediately since we don't have hit the database | |
defer.resolve(model); | |
} | |
// Remove model from collection | |
_.remove(this.models, model); | |
return remove; | |
}; | |
return this; | |
}; | |
// Return the constructor | |
return function(url, defaultParams){ | |
return new Collection(url, defaultParams); | |
}; | |
}]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment