Search code examples
javascriptjsonbackbone.js

How to get nested Backbone model and collections by theis path as like JSON?


I have the following JSON that represents my blog post data (just example):

var post = {
   id: 123,
   title: 'Sterling Archer',    
   comments: [
     {text: 'Comment text', tags: ['tag1', 'tag2', 'tag3']},
     {text: 'Comment test', tags: ['tag2', 'tag5']}
   ]  
}

Each unit of this JSON has appropriate Backbone's Model or Collection representation:

var PostModel = Backbone.Model.extend({
   parse: function (response) {
       if (response.comments) {
          response.comments = new Backbone.Collection(response.comments, {
              model: CommentModel
          });
       }
       return response;
   }    
});

var CommentModel = Backbone.Model.extend({
    parse: function (response) {
        if (response.tags) {
          response.tags = new Backbone.Collection(response.tags);
        }
        return response;
    }  
 });

 var post = new PostModel(post, {parse: true});

I need to store 'path' for each collection/model to be possible to get them something like the following:

post.get('/comments/0');       // comment model: {text: 'Comment text', tags: ['tag1', 'tag2', 'tag3']}
post.get('/comments/1/tags/1') // tag model with 'tag5'

It would be cool if possible get absolute path of model and/or colleciton That is the best approach to make this pissible?


Solution

  • You can override Backbone.Model Class, add custom _get method which support absolute path. here is override code

    Backbone.Model = Backbone.Model.extend({
    
      _get : function(path)
      {
          if(!path)
            return;
    
           var array = path.split('/');
           var that = this;
           var result = that;
           _.each(array, function(o, i){
                if(o && result)
                {
                    if(result instanceof Backbone.Collection)
                        result = result.at(o);
                    else if(result instanceof Backbone.Model)
                        result = result.get(o);
                    else if(_.isArray(result) || _.isObject(result))
                        result = result[o];
                    else
                        result = undefined;
                }
    
           });
           return result;
      }
    });
    

    this will support all data structure like, Model, Collection, Array, Object you can use it by

    post._get('/comments/0');      
    post._get('/comments/1/tags/1');