Adrian Florescu
Adrian Florescu

Reputation: 4492

Backbone.js - multiple models for one view

I have a template that needs to receive data from two different API endpoints (URLs): cart and user.

I want the two endpoints to act as one model or collection so that I can do something like .changedAttributes() or sync, or fetch.

I know Backbone is very permissive, but I am really lost.


Playground:

I've created a codepen to see what I've done so far: http://codepen.io/anything/pen/AXoBoa


Desired result should be something like:

initialize: function(){
  var self = this;
  collection.fetch({
  success: function(data){
      self.collection = data;
    }
  })
},

render: function(){
    var self = this;
    var source = $("#template").html();
    var template = Handlebars.compile(source);
    var htmlToRender = template(self.collection.toJSON());
}  

Upvotes: 0

Views: 737

Answers (2)

noahpc
noahpc

Reputation: 386

A slightly different approach to nikoshr based on http://backbonejs.org/#Events. The basic idea is that you set up an event object that can be referenced in both views. You can name the events whatever you want and they can triggered and listened to wherever the object is available.

  1. Create event object. In your case, add it to your main appshell object.

    appShell.Events = _.extend({}, Backbone.Events);
    
  2. When user performs action in user view like logout, trigger an event.

    appShell.Events.trigger('user:logout');
    
  3. Listen to the event in another view and perform action based off of it.

    this.listenTo(appShell.Events, 'user:logout', this.doSomething);
    
  4. Put logic in the doSomething to do whatever you need to do on the other view.

Upvotes: 1

nikoshr
nikoshr

Reputation: 33344

You could create an event concentrator listening to its registered objects and retrigger the events you catch.

Something like

var aggregate = _.extend({}, Backbone.Events);
aggregate.register = function(m) {
    var self = this;

    this.listenTo(m, 'all', function() {
        this.trigger.apply(this, arguments);
    });
};

You would then use it like this

aggregate.on('change', function(m) {
    // do what you have to do when one of the models change
    console.log('Change on ', m.toJSON());
});
aggregate.on('sync', function(m) {
    //same thing for syncs
    console.log('sync ', m.toJSON());
});

var m1 = new Backbone.Model({id: 1});
var m2 = new Backbone.Model({id: 2});
aggregate.register(m1);
aggregate.register(m2);

m1.fetch();
m2.set({data: 2});

And a demo http://jsfiddle.net/nikoshr/hm0xc79z/

Upvotes: 3

Related Questions