backbone.js - How to load only a subset of a collection's fields / have lazy model fields / lazy nested collections in a master detail scenario? -
i'm relatively new backbone, , i've searched while, , didn't find answer satisfies question (this 1 close, not sure it's applicable backbone.js master-detail scenario)
tl;dr: how represent subset (as in of collection's model's fields, not subset in paging / filtering) of collection? (e.g. list view shows name , modified date of something, when details includes not more fields, nested child collections)
now detailed version, here structure of application:
models
documentcollection
- collection of documents, should fetch name, , last modified datedocument
- when fetched part of collection fetch, should fetch name, , modification date, when fetched "standalone" (e.g. in details view) should fetch description , child articlesarticlecolletion
nested collection part of document, should fetched when document fetched in details view, should "lazy" , not fetched whendocumentcollection
fetchedarticle
views
documentcollectionview
(only shows document name, , last modified date)documentview
(includes document name, description , articles)articlesview
,articleview
showing single or collection of articles
goal
i have documentcollection
fetch
method call bring subset of document
model (only name , modified time), , when fetching document
directly, fetch description field , child articles
the real world models bit more complex more fields need cut traffic on wire , not load fields or sub collections before needed.
possible solutions
override fetch method, , apply relevant logic (e.g. flag "full" or "partial" load)
forget lazy fields, have nested collection lazy, cutting unused fields premature , unneded optimization, , it's not model's resposibility decide needed , not part of view rendering, should bring all
have different collection , model "summary" view, e.g.
documentsummarycollection
, have documentcollection extenddocumentsummarycollection
?
question
what of above (if any) "backbone" way of doing it? , there other approaches?
this 1 of common scenarios not sure there 'backbone' way handle. here 1 possible solution...
when fetch documents collection (/api/documents
) return json this:
[{id: 1, name: 'foo'}, {id: 2, name: 'bar'}]
when fetch document (/api/documents/1
), return json this:
{ id: 1, name: 'foo', description: 'some stuff foo', articles: [{id: 1, name: 'hello'}, {id: 2, name: 'hi again'}] }
when individual documentmodel fetched, there new attribute articles
. listen change:articles
event, , set
new json this.articles
articlescollection.
now... code:
var article = backbone.model.extend({}); var articlecollection = backbone.collection.extend({ model: article }); var document = backbone.model.extend({ constructor: function() { // make sure articles collection created. this.articles = new articlecollection(); backbone.model.prototype.constructor.apply(this, arguments); }, initialize: function(attributes, options) { this.articleschanged(); this.on('change:articles', this.articleschanged, this); }, // articles attribute changed. // set collection. // way, existing models updated, new ones added. articleschanged: function(){ // if document fetched , has articles json array, // set json this.articles collection. var articles = this.get('articles'); if(articles){ this.articles.set(articles); // remove 'articles' attribute set collection. this.unset('articles'); } } }); var documentcollection = backbone.collection.extend({ model: document });
some more code:
var docs = new documentcollection(); docs.fetch().done(function() { // docs has documents name, date attributes, // , empty articles collection. var doc = docs.at(0); var name = doc.get('name'); // foo var articlecount = doc.articles.length; // 0 doc.fetch().done(function() { // first doc full, articles, description, etc. doc.articles.each(function(article) { console.log(article.get('name')); }, this); // re-fetch collection later... check if new documents exist. docs.fetch().done(function() { // new docs added, removed docs gone. // existing doc models updated. }); }); });
i think main thing this, preserves documents/articles collection instances, when document collection, or individual document re-fetched later.
so, example, if showing documentmodel , articles collection in details view, , entire documentcollection re-fetched, documentmodel being shown still in collection after fetch (unless removed on server). nice if have change add remove
type events hooked instances.
with backbone 1.0 move towards 'update' fetch (which great), curious if there other (or better) solutions out there, pretty common issue... , haven't used exact solution , not sure ideal. used use parse
more grab child json , reset
child collection.. think ran problems with updating fetch, started trying this.
Comments
Post a Comment