简体   繁体   中英

Backbone.js - Where to define view helpers?

I've been kicking the tyres of Backbone.js and having a play around in recent weeks, so a bit of a noob question...

What is the 'correct' way to define and use view helpers in backbone.js?

As far as I can work out, the only real place to define helpers to use in your templates is on the model or collection itself. However, when that helper is directly returning HTML, this begins to feel a little dirty.

Is there a better way?

There are a few different places that I put view helpers with Backbone.js:

If the helper is specific to a certain view, put it right in the view definition:

var MyView = Backbone.View.extend({
  tagName: 'div',

  events: {
    ...
  },

  initialize: function() { ... },

  helperOne: function() {
    // Helper code
  },

  anotherHelper: function() {
    // Helper code
  },

  render: function() { 
    ... this.helperOne() ...
  }
});

If the helper will be used by all views, extend the Backbone View class so that all views inherit this function:

_.extend(Backbone.View.prototype, {
  helper: function() {
    // Helper code
  }
}

If you need more complicated sharing of helpers between views, have views extend each other:

var MyOtherView = MyView.extend({

  // ...

  render: function() { 
    ... this.helperOne() ...
  }
});

I'm not sure what is best practice (or if there is an established best practice), but these patterns seem fairly clean and work well.

Quick solution (CoffeeScript)

Backbone.View::handlebarsTemplate = (templateName) ->
  Handlebars.compile $(templateName).html()

Then you can use that in your view:

Yourcoolapp.Views.ThingsIndex extends Backbone.view

  initialize: ->
    @template = this.handlebarsTemplate("#hb_template")
    # etc...

  someMethod: =>
    @template = this.handlebarsTemplate("#hb_other")

As you build bigger Backbone apps, you'll probably want to namespace everything. Then you will have a place for global helpers. I haven't made the perfect namespace setup yet. But right now I'm doing something like this:

brainswap:{
  appView: {},          <== Reference to instantiated AppView class.
  classes = {           <== Namespace for all custom Backbone classes.
    views : {},
    models : {},
    collections: {},
    controllers : {},
    Router: null
  },
  models: {},          <== Instantiated models.
  controllers: {},     <== Instantiated controllers.
  router: {},          <== Instantiated routers.
  helpers: {},         <== Reusable helper platform methods.
  currentView: {},     <== A reference to the current view so that we can destroy it.
  init: function(){}   <== Bootstrap code to start app.
}

My view classes look something like this:

brainswap.classes.views.profile.contact = brainswap.classes.views.profile.base.extend({...

My controller is the object that instantiates new views (and places a reference in currentView . Remember you should always remove your last view so the previous views events all get unbinded and your reduce memory usage.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM