Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle relations in backbone.js [duplicate]

I'm stuck with how to design my backbone.js application regarding to my model relationships.

If I have an event model , that has a couple of relationships, say a user model can have many events and the event model in turn can have many comments and participations. A user can have many comments and the participation can have one user and one event. Wow, what a mess!

Event has many Comments
Event has many Participations
Event has one User

User has many Events
User has many Participations
User has many Comments

Comment has one Event
Comment has one User

Participation has one User
Participation has one Event

Okey, so my thought was to load a list of events when the user loads the page, and when a user clicks on an event load the rest of the information about that event (comments, participations and user).

So the question is, should I use some sort of global variable to hold all events, users and so on, and when I grab information from the server put it there (and check there before I grab something from the server), maybe in some sort of localstorage (and how do I do this using backbone-relational?).

Another idea I've had is to let every event have its own independent data, the problem with this is that I will probably send redundant data every time I click on an event.

What way do you recommend?

thanks!

like image 861
jonepatr Avatar asked Jun 03 '12 15:06

jonepatr


1 Answers

Like @mu_is_too_short commented, Backbone-relational might be something you are interested in looking into. With Backbone-relational your models and submodel collections are automatically created and events can be managed across the parent-child relationship.

I'll just give you some sample code so you can get a taste for it. Part of your example code might look something like this.

User has many Events:

User = Backbone.RelationalModel.extend({
    relations: [
        type: Backbone.HasMany,   // Type of relationship
        key: 'events',            // How we reference the sub-models in collection
        relatedModel: 'Event',    // The sub-model type
        collectionType: 'EventCollection',  // The sub-model collection
        reverseRelation: {
            key: 'belongsToUser'            // Key we use to refer to the parent
        }
    ],
    // Other Backbone.Model properties and functions
});

When you create a Backbone-relational model, it automatically creates a collection of submodels for you named after the 'key' that you designate. So each user that you have will have it's own collection of related events tidy-ed up.

Basically, when you create or fetch the User, you give it references to the related models that it needs. So for example, your User id=1 might need Event 5, 7, and 11. (I'm just using IDs). As long as these references are defined in array form then you can lazily load them using Relational's fetchRelated methods.

myUser = new User();
myUser.set({
    name: 'RayMysterio',
    age: '26',
    events: [5, 7, 11]    // Or this might just come with the User object from your server
});

myUser.fetchRelated('events');
// This will go fetch the related events for this user model from the URL you designate.

myUser.get('events');
// The collection of events are treated like an attribute of the User model.

myUser.get('events').find(function(eventModel){
    return // some find condition - or whatever you want to do on that collection
});

You might want to bind certain listeners to the sub-models.

myUser.bind('add:events', function(model, collection) {
    // Whatever code you want to happen when new models are added to the user events coll
});

Etc. Etc.

It's a nice way of producing one to one, one to many, and inverse relationships. This is pretty key. When you define a relationship between models and you create a model.

E.g. you create a new instance of User model.

Backbone-relational automatically creates the inverse link (Event model has an attribute defined by the reverse relation key 'belongsToUser' (or whatever you name it). This makes it pretty handy to traverse up and down the model/sub-model hierarchy.

Based on your relational needs this seems like a good fit.

If you want many to many, there is a round-about way of doing it (using intermediate models) but I've found this to be kind of wonky and I avoid it. Paul-Uithol has been updating Backbone-Relational for some time and new features keep getting added in. The learning curve was a little hard for me at first but once you start getting used to it it's mighty handy.

NOTE: Just to emphasize, Mosselman recommended Require.js and I also strongly agree with this. It has made my code much more manageable. You can tinker (wrap) the Backbone-relational code to make it AMD compliant and it works flawlessly with Require.

UPDATE: backbone-relational now supports require.js as of release 0.8.8 on April 1, 2014 - thanks Kenneth

like image 162
jmk2142 Avatar answered Nov 05 '22 13:11

jmk2142