[フレーム]
Last Updated: February 25, 2016
·
2.885K
· plukevdh

Use Handlebars.js with Backbone.js

class Mustachio extends Backbone.View
 render: (template_id, context) ->
 @templates[template_id].call @, context

 @prepare = ->
 templates = {}

 $('script[type="text/x-handlebars-template"]').each ->
 raw_template = this.textContent
 raw_template = this.innerHTML unless raw_template # IE 8

 templates[this.id] = Handlebars.compile(raw_template)

 @::templates = templates

window.Mustachio = Mustachio

$ ->
 Mustachio.prepare()

Let's dissect.

Mustachio.prepare() crawls the page, finds all the handlebars templates, compiles and caches them. This allows render to simply do a lookup and then call the template with the context.

With your views, you can extend the Mustachio class:

class IdeaList extends Mustachio
 events:
 "click .delete": 'delete'

 delete:
 @model.delete()
 @remove()

 render:
 html = super('idea-item', context)

 @options.parent.$el.append html
 @setElement("#idea-#{@model.get('id')}")

Since Mustachio is the parent class, calling super looks up the cached template, renders it and returns the rendered HTML for use. Alternatively, if there is nothing else you need to do, just omit the render method from your model and just allow render to be called on the parent class.

@tjsingleton recommended one additional performance gain for the page load. Instead of crawling and compiling at page load, lazy compile the templates on first request. This would look like the following (with duplicate code removed for brevity):

class Mustachio extends Backbone.View
 templates: {}

 lazyCompileFactory: (template_id, raw_template) ->
 @templates[template_id] = (context) =>
 compiled_template = Handlebars.compile(raw_template)
 @templates[this.id] = compiled_template
 compiled_template(context)

 @prepare = ->
 $('script[type="text/x-handlebars-template"]').each (i, item) =>
 raw_template = item.textContent
 raw_template = item.innerHTML unless raw_template # IE 8

 @::lazyCompileFactory(item.id, raw_template)

Here's the two versions in a gist for easier comparison:

https://gist.github.com/plukevdh/5459841

AltStyle によって変換されたページ (->オリジナル) /