In Backbone JS when I fetch a collection should I be fetching the entire collection or a small portion of it?
For example I have news feed collection in mongoDB that could have potentially 1000s of items. When the user hits the page I only want to show them the latest 10 items with the option to 'Load More'. But if 开发者_如何学JAVAthey visit a specific item via URL http://site.com/#/feed/:itemID
I want to be able to pull up that item's record.
1. How many document should I be fetching initially?
2. How would I got about fetching any item by id?
I ended up using the {add: true}
statement when calling fetch on my collection. This prevents the collection from being replaced by the result of the fetch and but instead appends the result to the collection. I then also passed the 'skip' amount using the {data: {skip: amountOfItemsInCollectionAlready }
, this is used on the server-side to get the correct batch of items from the database.
My final fetch method looks like this:
loadMore: function(e){
this.collection.fetch({
add: true,// this adds to collection instead of replacing
data:{// this is optional params to be sent with request
skip: this.collection.length// skip the number of items already in the collection
}
});
}
You probably don't want to just use Collection.fetch()
, because you won't get the benefit of client-side caching - it'll drop the items you've already loaded from the server and reset the collection. You will probably need to extend Backbone.Collection
with a custom function to retrieve more items. I used the following code in a recent project:
Backbone.Collection.extend({
// fetch list without overwriting existing objects (copied from fetch())
fetchNew: function(options) {
options = options || {};
var collection = this,
success = options.success;
options.success = function(resp, status, xhr) {
_(collection.parse(resp, xhr)).each(function(item) {
if (!collection.get(item.id)) {
collection.add(item, {silent:true});
}
});
if (!options.silent) collection.trigger('reset', collection, options);
if (success) success(collection, resp);
};
return (this.sync || Backbone.sync).call(this, 'read', this, options);
}
});
This is mostly copied from the default fetch()
code, but instead of dropping existing items it will add new ones. You'd probably want to implement something server-side, using the options
object as Julien
suggests to pass in the parameters of what items you want to load, probably either a page number (if you want to control page size on the server) or a start-stop pair (if you want to control it on the client).
1 - You should be fetching 10
Add a page argument to your collection and have the backend code return the page matching (10/page). /my_objects?page=2 to get records 10-20 etc.
You do this like this (untested):
collection.fetch({data: {page:2}})
Or you alter the URL directly
2 - To fetch an item by ID you create the model
object = new Model({id: 1})
and fetch it
object.fetch()
精彩评论