0

I am a novice to Backbone.js. I am trying to create a UI where I have multiple tables. There are 2 separate URLs that provide data in JSON format. 1st url gives the structure of the table,i.e., the column headers, the width, a corresponding dbfield name where the data in the table will come from. The 2nd url gives the data for a table. This url takes an id as parameter that is available in the first url. So for eg., there are 4 tables then the 1st url will give the structure details of all the 4 tables and the 2nd url will need to be called 4 times for the different id's for the tables and rendered.

Any suggestions on how to do this using Backbone.js. I have been able to work with the 1st url and create the 4 tables but need help on how to add the data from the 2nd url to the table by looping thru the 1st collection and calling the 2nd url.

Appreciate any assistance with this.

thanks.

Following is the backbone code I use to get the data from 1st url and pass it to my template to generate the html. One of the fields coming in this data is a parameter for the 2nd url.

var mModel = Backbone.Model.extend();

var Collection = Backbone.Collection.extend({
    model: mModel,
    url: 'http://xyz.com/sendjson',

    initialize: function () {
        this.deferred = this.fetch();
    }
});

var View = Backbone.View.extend({
    render: function () {

        var collection = this.collection;

        collection.deferred.done(function () {

            var template = _.template($('#template').html(),
            {
                Collection: Collection
            });
            $('#main').html(template);
        });
    }
});

var myCollection = new Collection();

var myView = new View({
    collection: myCollection
});

myView.render();
Amit
  • 33
  • 5
  • The 1st url should come from Backbone-Model and 2nd url should come from Backbone-Collection. As Backbone-Collection is collection of Backbone-Model. – Ashwin Hegde May 31 '13 at 11:09
  • So you need 1 model to get the table structure and 1 collection to get the table data....Am i write? Wait can you edit and write some code...i think i have done this before.... – Ashwin Hegde May 31 '13 at 11:11
  • At the moment in my code, the 1st url is in the collection. The model is just the default onevar mModel = Backbone.Model.extend();. My code works even if I don't mentioned the model inside my collection. – Amit May 31 '13 at 11:26
  • Some code might help here to understand the case in details at coding level. – Ashwin Hegde May 31 '13 at 11:39
  • This is tricky - do you have access to the server-side? Best bet might be to export a single api method from there. – Lyn Headley May 31 '13 at 14:53
  • Hi Lyn, Yes, that was the first thing I tried to do was to see if the 2 api's can be merged. But unfortunately that's the way its going to be as the server side is not in my control. – Amit May 31 '13 at 15:19

1 Answers1

0

Ok here is what I came up with. It uses two separate collections. I tested this locally and it worked for me.

       var mUrl = '/sendjson'
       var iUrl = '/senditem'

       var mCollection, iCollection

       var MModel = Backbone.Model.extend({})
       var IModel = Backbone.Model.extend({urlRoot: iUrl})

       var IView = Backbone.View.extend({
           template: '<%= mModel.color %><%= iModel.name %>',
           render: function() {
               var html = _.template(this.template, {
                   mModel: this.mModel.toJSON(), 
                   iModel: this.iModel.toJSON()
               })
               this.$el.html(html)
               return this
           }
       })

       var MCollection = Backbone.Collection.extend({
           model: MModel,
           url: mUrl
       });

       var ICollection = Backbone.Collection.extend({
           initialize: function(app, ids) {
               var self = this
               _.each(ids, function(id) { 
                   var iModel = new IModel({ id: id })
                   self.add(iModel)
                   app.listenTo(iModel, 'sync', function() {
                       var view = app.mCollection.get(iModel.id).view
                       view.iModel = iModel
                       app.$el.append(view.render().$el)
                   });
                   iModel.fetch()
               });
           }
       });

       var App = Backbone.View.extend({
           el: '#main',

           initialize: function() {
               this.mCollection = new MCollection()
               var app = this

               this.mCollection.on('sync', function () {
                   app.mCollection.each(function(mModel) {
                       var iview = new IView()
                       iview.mModel = mModel
                       iview.iModel = new IModel
                       mModel.view = iview
                   })
                   app.render()
                   var items = new ICollection(app, 
                      app.mCollection.map(function(mModel) {
                      return mModel.get("parent").child1.child2.id;
                   });

               this.mCollection.fetch();
           },

           render: function () {
               var that = this
               this.mCollection.each(function(mModel) { 
                   that.$el.append(mModel.view.render().$el) 
               });
           }
       });
Lyn Headley
  • 11,368
  • 3
  • 33
  • 35
  • Thanks Lyn. I'll try this suggestion out and get back. – Amit Jun 03 '13 at 10:39
  • I am trying to implement this. One more complication I have is that the Url that I need to build at run time needs to look something like the following: http://xyz.com?sendJSON={"parameter":{"id":1,"p2":"v2","p3":"v3","p4":v4,"p5":v5,"p6":v6},"f1":"vf1"}. Not sure how to do this. – Amit Jun 03 '13 at 14:59
  • you can override model.url() for this. – Lyn Headley Jun 03 '13 at 15:47
  • Hi @Lyn, The json from the 1st url that I have to work with is very complex with multiple child nodes to get to the id field that needs to be picked and passed to the 2nd url. Having some issue implementing your suggestion. If possible can you pls include a working sample in say jsfiddle including the data that you used. Thanks for all your assistance so far. – Amit Jun 04 '13 at 10:37
  • This should be a matter of grabbing the id's out of the child object. I've updated the call to new ICollection to illustrate. – Lyn Headley Jun 04 '13 at 21:31