backbone-data
Advanced tools
Comparing version 0.0.1 to 0.0.2
API Documentation | ||
================= | ||
Until I get full documentation up, see the test files for examples. | ||
### DS.defineResource(resourceDefinition) | ||
@@ -23,3 +21,3 @@ | ||
name: 'person', | ||
idAttribute: 'id', | ||
idAttribute: 'id', // 'id' is the default | ||
model: Person, | ||
@@ -82,5 +80,5 @@ collection: PersonCollection | ||
### DS.findAll(resourceName) | ||
### DS.findAll(resourceName [, options]) | ||
Asynchronously fetch all models and inject them into the store. Returns a promise. | ||
Asynchronously fetch all models once and inject them into the store. Returns a promise. Subsequent requests will just resolve with what is in the cache. | ||
@@ -92,2 +90,15 @@ ```js | ||
}); | ||
``` | ||
Sometimes you need to load incomplete models in the store and have details for each of those models fetched and cached later based on user actions. You can load these incomplete models into the store, and if more details about a model are needed, _DS.find()_ will request those details once, thus completing the model in the store, and any subsequent calls to DS.find for a particular model won't make any HTTP requests. | ||
```js | ||
// Makes AJAX request to a URL like /people | ||
DS.findAll('person', { incomplete: true }).done(function(collection) { | ||
// Makes AJAX request to a URL like /people/33 to get all person 33 details and caches details | ||
DS.find('person', 33).done(function(model) { | ||
// Does NOT make AJAX request. Pulls person 33 from cache | ||
DS.find('person', 33).done(function(model) {}); | ||
}); | ||
}); | ||
``` | ||
@@ -99,3 +110,3 @@ | ||
Fetching a model not in the store: | ||
##### Fetching a model not in the store: | ||
@@ -109,3 +120,3 @@ ```js | ||
Fetching a model that is already in the store | ||
##### Fetching a model that is already in the store | ||
@@ -121,3 +132,3 @@ ```js | ||
Sometimes you have incomplete models loaded in the store and you need to retrieve and cache more details about a model. This is particularly useful if you have your server-side dump out json data containing incomplete models. You can load these incomplete models into the store, and if more details about a model are needed, DS.find will request those details once, thus completing the model in the store and any subsequent calls to DS.find for a particular model won't make any HTTP requests. | ||
Sometimes you need to load incomplete models in the store and have details for each of those models fetched and cached later based on user actions. You can load these incomplete models into the store, and if more details about a model are needed, _DS.find()_ will request those details once, thus completing the model in the store, and any subsequent calls to DS.find for a particular model won't make any HTTP requests. | ||
@@ -124,0 +135,0 @@ ```js |
{ | ||
"name": "backbone-data", | ||
"description": "A simple data store for backbone models and collections inspired by Ember Data and angular-data.", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"homepage": "https://github.com/skaterdav85/backbone-data", | ||
"authors": [ | ||
"David Tang" | ||
], | ||
"license": "MIT", | ||
"keywords": [ | ||
"backbone data store", "data store", "DS", "Backbone.js", "Ember Data", "angular-data" | ||
], | ||
"main": "dist/backbone-ds.min.js", | ||
@@ -21,3 +24,4 @@ "dependencies": { | ||
"tests" | ||
] | ||
], | ||
"license": "MIT" | ||
} |
@@ -6,2 +6,3 @@ (function(window, undefined) { | ||
var incomplete = {}; | ||
var collectionStatus = {}; | ||
@@ -186,11 +187,17 @@ /** | ||
/** | ||
* Request a collection from the server and inject models in store. | ||
* Request a collection from the server once and inject models in store. | ||
* This does reset the collection for resourceName. | ||
* Still debating on if this is what it should do... | ||
*/ | ||
DS.findAll = function(resourceName) { | ||
DS.findAll = function(resourceName, options) { | ||
var collection = store[resourceName]; | ||
var dfd = $.Deferred(); | ||
if (collectionStatus.hasOwnProperty(resourceName)) { | ||
dfd.resolve(collection); | ||
return dfd.promise(); | ||
} | ||
return collection.fetch().then(function(models) { | ||
DS.inject(resourceName, models); | ||
DS.inject(resourceName, models, options); | ||
collectionStatus[resourceName] = 'completed'; | ||
return collection; | ||
@@ -267,2 +274,3 @@ }, function() { | ||
incomplete = {}; | ||
collectionStatus = {}; | ||
@@ -269,0 +277,0 @@ return this; |
@@ -1,1 +0,1 @@ | ||
!function(e){function n(e,n){var t,r=i[e].idAttribute;c[e]=c[e]||{},_.isArray(n)?n.forEach(function(n){var t=n[r];c[e][t]=!0}):(t=n[r],c[e][t]=!0)}function t(e,n){return c[e]?c[e][n]:!1}var r={},i={},o={},c={};r.defineResource=function(e){var n,t=["idAttribute","name","collection","model"];if(t.forEach(function(n){if(!e.hasOwnProperty(n)||!e[n])throw new Error(n+" must be specified when defining a resource")}),n=e.name,i[n])throw new Error(n+" resource has already been defined!");return i[n]=e,o[n]||(o[n]=new e.collection),this},r.createInstance=function(e){return new i[e].model},r.inject=function(e,t,r){var i;return r=_.extend({incomplete:!1},r),i=o[e],r.incomplete&&n(e,t),i.add(t)},r.get=function(e,n){var t,r,c=i[e].idAttribute,u={};return r=o[e],r&&(u[c]=n,t=r.findWhere(u))?t:null},r.getAll=function(e){return o[e]},r.ejectAll=function(e){var n=o[e];n&&n.reset()},r.find=function(e,n){var o,u={},f=i[e].idAttribute,d=this.get(e,n),a=$.Deferred();return d?t(e,n)?d.fetch().then(function(){return delete c[e][n],d}):(a.resolve(d),a.promise()):(u[f]=n,o=new i[e].model(u),o.fetch().then(function(){return r.inject(e,o),o},function(){throw new Error("error fetching model: "+n)}))},r.findAll=function(e){var n=o[e];return n.fetch().then(function(t){return r.inject(e,t),n},function(){throw new Error("error fetching collection: "+e)})},r.where=function(e,n){var t=o[e],r=i[e].collection,c=new r,u=t.where(n);return c.add(u),c},r.filter=function(e,n){var t=o[e],r=i[e].collection,c=new r,u=t.filter(n);return c.add(u),c},r.update=function(e,n,t){var r=this.get(e,n);return r.set(t),r.save().then(function(){return r})},r.create=function(e,n){i[e].idAttribute;return n.save().then(function(){return o[e].add(n),n})},r.destroy=function(e,n){var t=this.get(e,n);return t.destroy()},r.reset=function(){return o={},i={},c={},this},e.DS=r,"function"==typeof define&&define.amd&&define(["backbone"],function(){return r})}(window); | ||
!function(e){function n(e,n){var t,r=i[e].idAttribute;c[e]=c[e]||{},_.isArray(n)?n.forEach(function(n){var t=n[r];c[e][t]=!0}):(t=n[r],c[e][t]=!0)}function t(e,n){return c[e]?c[e][n]:!1}var r={},i={},o={},c={},u={};r.defineResource=function(e){var n,t=["idAttribute","name","collection","model"];if(t.forEach(function(n){if(!e.hasOwnProperty(n)||!e[n])throw new Error(n+" must be specified when defining a resource")}),n=e.name,i[n])throw new Error(n+" resource has already been defined!");return i[n]=e,o[n]||(o[n]=new e.collection),this},r.createInstance=function(e){return new i[e].model},r.inject=function(e,t,r){var i;return r=_.extend({incomplete:!1},r),i=o[e],r.incomplete&&n(e,t),i.add(t)},r.get=function(e,n){var t,r,c=i[e].idAttribute,u={};return r=o[e],r&&(u[c]=n,t=r.findWhere(u))?t:null},r.getAll=function(e){return o[e]},r.ejectAll=function(e){var n=o[e];n&&n.reset()},r.find=function(e,n){var o,u={},f=i[e].idAttribute,d=this.get(e,n),a=$.Deferred();return d?t(e,n)?d.fetch().then(function(){return delete c[e][n],d}):(a.resolve(d),a.promise()):(u[f]=n,o=new i[e].model(u),o.fetch().then(function(){return r.inject(e,o),o},function(){throw new Error("error fetching model: "+n)}))},r.findAll=function(e,n){var t=o[e],i=$.Deferred();return u.hasOwnProperty(e)?(i.resolve(t),i.promise()):t.fetch().then(function(i){return r.inject(e,i,n),u[e]="completed",t},function(){throw new Error("error fetching collection: "+e)})},r.where=function(e,n){var t=o[e],r=i[e].collection,c=new r,u=t.where(n);return c.add(u),c},r.filter=function(e,n){var t=o[e],r=i[e].collection,c=new r,u=t.filter(n);return c.add(u),c},r.update=function(e,n,t){var r=this.get(e,n);return r.set(t),r.save().then(function(){return r})},r.create=function(e,n){i[e].idAttribute;return n.save().then(function(){return o[e].add(n),n})},r.destroy=function(e,n){var t=this.get(e,n);return t.destroy()},r.reset=function(){return o={},i={},c={},u={},this},e.DS=r,"function"==typeof define&&define.amd&&define(["backbone"],function(){return r})}(window); |
@@ -5,3 +5,3 @@ { | ||
"description": "A simple data store for backbone models and collections inspired by Ember Data and angular-data.", | ||
"version": "0.0.1", | ||
"version": "0.0.2", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "type": "git", |
@@ -14,6 +14,6 @@ Backbone Data | ||
* Manages singletons for each collection type. Many times you'll need the same collection instance in multiple views. Just ask for a collection type from the store (_DS.getAll('person')_, _DS.findAll('person')_) and it will return/resolve with the same collection instance each time. | ||
* Load incomplete models into the store to be completed and cached later. Imagine you have an array of product objects bootstrapped onto the page from the server. Each product object is incomplete, lacking extra details that may or may not be needed based on user actions. With the data store, you can load these incomplete product models and specify that they are incomplete. Based on the user's actions, if details are needed, the store will fetch the details once, merge the details into the model thus completing it, and always return/resolve that completed cached model. | ||
* Load models into the store specified as incomplete (lacking details). Extra details about the model can be fetched and cached on subsequent requests. Particularly useful if your models have a lot of data that might not be needed. | ||
* Easily create new filtered collections | ||
* AMD compatible | ||
* 773 bytes gzipped and minified | ||
* 802 bytes gzipped and minified | ||
@@ -28,2 +28,14 @@ ### Install | ||
Or install through Bower | ||
``` | ||
bower install backbone-data | ||
``` | ||
Or install through NPM | ||
``` | ||
npm install backbone-data | ||
``` | ||
This library exposes a global variable called _DS_ (Data Store) and it is also registers itself for AMD (Require.js). | ||
@@ -47,3 +59,3 @@ | ||
* DS.find(resourceName, id [, options]) - Resolves with the model retrieved and injected into the store | ||
* DS.findAll(resourceName) - Resolves with the collection instance managed by the store for _resourceName_ | ||
* DS.findAll(resourceName [, options]) - Resolves with the collection instance managed by the store for _resourceName_ | ||
* DS.create(resourceName, model) - Resolves with the newly created and injected model | ||
@@ -50,0 +62,0 @@ * DS.destroy(resourceName, id) - Destroy a model in the store |
@@ -6,2 +6,3 @@ (function(window, undefined) { | ||
var incomplete = {}; | ||
var collectionStatus = {}; | ||
@@ -186,11 +187,17 @@ /** | ||
/** | ||
* Request a collection from the server and inject models in store. | ||
* Request a collection from the server once and inject models in store. | ||
* This does reset the collection for resourceName. | ||
* Still debating on if this is what it should do... | ||
*/ | ||
DS.findAll = function(resourceName) { | ||
DS.findAll = function(resourceName, options) { | ||
var collection = store[resourceName]; | ||
var dfd = $.Deferred(); | ||
if (collectionStatus.hasOwnProperty(resourceName)) { | ||
dfd.resolve(collection); | ||
return dfd.promise(); | ||
} | ||
return collection.fetch().then(function(models) { | ||
DS.inject(resourceName, models); | ||
DS.inject(resourceName, models, options); | ||
collectionStatus[resourceName] = 'completed'; | ||
return collection; | ||
@@ -267,2 +274,3 @@ }, function() { | ||
incomplete = {}; | ||
collectionStatus = {}; | ||
@@ -269,0 +277,0 @@ return this; |
@@ -51,2 +51,47 @@ describe('find()', function() { | ||
}); | ||
it('should allow you to specify if models fetched are incomplete', function(done) { | ||
var spy = sinon.spy(Backbone.Model.prototype, 'fetch'); | ||
var server = sinon.fakeServer.create(); | ||
server.respondWith("GET", "/people", | ||
[200, { "Content-Type": "application/json" }, | ||
'[{ "id": 33, "name": "Gwen", "age": 43 }]']); | ||
server.respondWith("GET", "/people/33", | ||
[200, { "Content-Type": "application/json" }, | ||
'{ "id": 33, "name": "Gwen", "age": 43, "gender": "F" }']); | ||
DS.findAll('person', { incomplete: true }).done(function(collection) { | ||
DS.find('person', 33).done(function(model) { | ||
expect(model.toJSON()).to.eql({ "id": 33, "name": "Gwen", "age": 43, "gender": "F" }); | ||
DS.find('person', 33).done(function(model) { | ||
expect(spy.callCount).to.equal(1); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
server.respond(); | ||
server.respond(); | ||
server.restore(); | ||
}); | ||
it('should pull from cache if fetch() has already been called', function(done) { | ||
var spy = sinon.spy(Backbone.Collection.prototype, 'fetch'); | ||
var server = sinon.fakeServer.create(); | ||
server.respondWith("GET", "/people", | ||
[200, { "Content-Type": "application/json" }, | ||
'[{ "id": 33, "name": "Gwen", "age": 43 }]']); | ||
DS.findAll('person').done(function(collection) { | ||
DS.findAll('person').done(function(collection) { | ||
expect(spy.callCount).to.equal(1); | ||
done(); | ||
}); | ||
}); | ||
server.respond(); | ||
server.restore(); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
50752
1222
79