Skip to content

Instantly share code, notes, and snippets.

@fourcolors
Created January 29, 2013 18:19
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fourcolors/4666340 to your computer and use it in GitHub Desktop.
Save fourcolors/4666340 to your computer and use it in GitHub Desktop.
# Extends Backbone.View on top of itself with some added features
# we use regularly
class Backbone.View extends Backbone.View
##
# Manages child views and renders them whenever the parent view is rendered.
# Specify views as key:value pairs of `className: view` where `className` is
# a CSS className to find the element in which to to append a rendered
# `view.el`
#
# Be sure to call `super` in the parent view's `render` method _after_ the
# html has been set.
views: false
# example: new ExampleView
##
# Define default options, options passed in to the view will overwrite these
defaults:
# can hand a view a template option to avoid subclasses that only add a
# different template
template: null
initialize: (options) ->
@options = _.extend {}, @defaults, @options, options
@setTemplate()
@$el.data 'view', this
this
setTemplate: ->
@template = @options.template if @options.template
##
# Extends render to add support for chid views and element filtering
render: (opts = {}) =>
@renderEl()
@_afterRender()
this
renderEl: ->
@$el.html @template(@toJSON()) if @template
##
# Internal afterRender
# @api private
_afterRender: ->
@cacheEls() if @els
@$('[data-bind]').each @createBinding
@afterRender()
# its important for renderViews to come last so we don't filter
# and cache all the child views elements
@renderViews() if @options.views
##
# Add behavior and bindings to elements.
afterRender: ->
##
# in charge of getting variables ready to pass to handlebars during render
# override with your own logic to do something fancy.
toJSON: ->
json = ((@model ? @collection)?.toJSON arguments...) || {}
json.cid = @cid
json
##
# Renders all child views
#
# @api private
renderViews: ->
_.each @options.views, @renderView
##
# Renders a single child view and appends its designated element
# Use ids in your view, not classes. This
#
# @api private
renderView: (view, selector) =>
target = @$("##{selector}")
target = @$(".#{selector}") unless target.length
view.setElement target
view.render()
@[selector] ?= view
Backbone.View
# SOME ROUTER/BUNDLE/OTHER JS FIlE
current_user = new User ENV.CURRENT_USER
todos = new ToDoCollection
todos.fetch()
indexView = new IndexView
el: 'body'
views:
"#header" : new HeaderView
model: current_user
"#todos" : new ToDoView
collection: todos
indexView.render()
# note you could leave out the el: 'body' and just do
# something like $('body').html indexView.render().e
class IndexView extends Backbone.View
# No need to call render or initialize
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment