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 date
    • document - when fetched part of collection fetch, should fetch name, , modification date, when fetched "standalone" (e.g. in details view) should fetch description , child articles
      • articlecolletion nested collection part of document, should fetched when document fetched in details view, should "lazy" , not fetched when documentcollection fetched
        • article

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

  1. override fetch method, , apply relevant logic (e.g. flag "full" or "partial" load)

  2. 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

  3. have different collection , model "summary" view, e.g. documentsummarycollection , have documentcollection extend documentsummarycollection?

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

Popular posts from this blog

monitor web browser programmatically in Android? -

Shrink a YouTube video to responsive width -

wpf - PdfWriter.GetInstance throws System.NullReferenceException -