Barry
Barry

Reputation: 1587

BackboneJS: How to assign multiple models in a single view

How do you call multiple models in a single view

Usual case is that you create a backbone model

var myModel = Backbone.Model.extend({ url:"api/authentication"});

and then assign it to a view, making it the default model of a certain view

    var LoginView = Backbone.View.extend({
        model: new myModel(),
        initialize: function(){
            _.bindAll(this, 'render', 'render_thread_summary', 'on_submit', 'on_thread_created', 'on_error');
            this.model.bind('reset', this.render); 
            this.model.bind('change', this.render); 
            this.model.bind('add', this.render_thread_summary); 
        },
        ...
    });

But I have many methods in a single view that calls different models. Currently I just create an instance of a model inside an event method.

The other solution that I'm thinking would be like this

initialize: function(){
   _.bindAll(this, 'render', 'render_thread_summary', 'on_submit', 'on_thread_created', 'on_error');
   new.model1().bind('reset', this.render); 
   new.model2().bind('change', this.render); 
   new.model3().bind('add', this.render_thread_summary); 
},

But are these good practices? What else are the other way to do this. Thanks.

UPDATE In response to Peter, here's my actual code

var userRegModel                = Backbone.Model.extend({url: fn_helper.restDomain()+'user/reg'});
var userResendActivationModel   = Backbone.Model.extend({url: fn_helper.restDomain()+'user/token/activation/new'});
var userResetPassModel1         = Backbone.Model.extend({url: fn_helper.restDomain()+'user/pwdreset/token/new'});
var userResetPassModel2         = Backbone.Model.extend({url: fn_helper.restDomain()+'user/pwdreset/change'});
var userLoginModel              = Backbone.Model.extend({url: fn_helper.restDomain()+'user/login'});

_view:  Backbone.View.extend({
                el:             'div#main-container',
                initialize:     function(){},
                events: {
                    'click #user-signup':            'signupUserFn', //userRegModel 
                    'click a#activation-resend':     'resendActivationFn',//userResendActivationModel
                    'click #reset-password-submit1': 'execResetPasswordFn', //userResetPassModel1
                    'click #reset-password-submit2': 'execResetPasswordFn', //userResetPassModel2

Each models declared above corresponds to different methods declared in events

Upvotes: 1

Views: 1044

Answers (1)

Peter Lyons
Peter Lyons

Reputation: 146154

  • Normally model instances should be passed to views in the options argument to the initialize method.

Generally models represent data that either is currently or will eventually be stored in database somewhere. Now, sometimes you want to create a model just for managing ephemeral browser state, which is fine, but the common case is that most read/edit/delete views don't create models unless that's their primary purpose like a "Post New Comment" form. So normally if your view has to show some models, allow them maybe to be updated and saved, they should come into the view in the options argument to the initialize function.

However, if your view really needs so many models and nothing else in your system cares about them, just create them during initialize and store them directly as properties on this (your view instance) and off you go.

If you post a more complete code sample, we can give specific recommendations, but as it is it looks like if you have a LoginView and you need more than 1 model for it, you might be off in the weeds design-wise.

Part Deux

OK, so it looks like you think every API endpoint needs a model. Just implement those as methods on a single model class that use Backbone.sync with the appropriate url option.

var Model = Backbone.Model.extend({
    resendActivation: function () {
        return Backbone.sync.call('update', this, {url: fn_helper.restDomain()+ 'user/token/activation/new'});
    }
});

You may have to do some manual triggering of events and I'm not sure what your API returns, but fundamentally these are all dealing with a single user record and can be handled by a single model.

Misc unrelated tips:

  • _.bindAll(this); //don't bother listing methods out
  • this.model.on('reset change', this.render); //bind multiple events at once
  • JavaScript by vast majority convention use camelCase not lower_with_underscores

Upvotes: 4

Related Questions