Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js: The right way to refactor view code?

I'm wondering about where to place common backbone view code. For example, I have the following in my "NewPosts" view:

  createPost: (event) ->
    #...
    @collection.create attributes,
      #...
      error: @handleError


  handleError: (entry, response) ->
    if response.status == 422
      #...

That handleError function is going to be used amongst a LOT of different views...I'm not sure on best practices re: where to place this. Is there a backbone equivalent of view helpers I can put this in? Any other methods of attack?

like image 491
PlankTon Avatar asked Feb 19 '23 16:02

PlankTon


1 Answers

NOTE: My CoffeeScript is rusty, so I'm answering this in JS, but the idea should translate.

Obviously, one way to solve this is to give all your views a parent class, and then put methods like handleError in that class. However, if you're looking for a more "mixin" like way of adding methods, you can do that too.

Backbone views are initialized with an argument to the extend method, like so:

var MyView = Backbone.View.extend({
    someMethod: function(){ doSomething();}
});

That argument isn't anything magical; it's just a JS object, so you can extend it using _.extend, like so:

var myCommonMethods = {
    handleError: function ...
}

var MyView = Backbone.View.extend(_({
    someMethod: function(){ doSomething();}
}, myCommonMethods));

The advantage of this approach is that you can "mix in" as many method sets as you want, whereas if you use a parent class you're much more constrained. The parent class approach is simpler though:

var BaseView = {
    handleError: function ...
}

var MyView = BaseView.extend({
    someMethod: function(){ doSomething();}
});

so it really just depends on your particular needs.

Personally, in my code I use both approaches: I have a BaseView that all of my views extend, and I put extremely common logic (like our templating system, which most of our views use) in to it. I then have "mix-ins" of various method sets that add additional functionality.

For instance, I have a mix-in set of methods for all views that have a "select" element as their el; this let's those views have whatever base class makes sense for them, but still also have a common set of methods (eg. they all have a selectOption method which lets me add a "selected" attribute to a particular option inside the view's el). Hope that helps.

like image 91
machineghost Avatar answered Feb 21 '23 05:02

machineghost