Skip to content

Instantly share code, notes, and snippets.

@austbot
Created June 8, 2015 05:33
Show Gist options
  • Save austbot/96a78a49fd607fa83b5b to your computer and use it in GitHub Desktop.
Save austbot/96a78a49fd607fa83b5b to your computer and use it in GitHub Desktop.
Renderable
uuid = require('./uuid')
merge = require('merge')
###*
# Renderable - Constructs a rederable object.
#
# @param {htmlElement} parent the parent element that the template needs to be rendered into.
# @param {handlebars_template} template a precompiles handlebars template
# @return {this}
###
Renderable = (parent, template, model) ->
#Generate a unique id or get it from the child.
@id = @id or 'renderable-' + uuid.generate()
#We dont want to use jquery as a dependancy for this class so we convert if we need to.
if parent
@parent = parent
#Initialize class vars
@element = undefined
#The key name of the template
@template_str = template
#State Variable
@rendered = false
#Load template from this.template
@getTemplate()
Renderable::updateModel = (data) ->
@model = data
###*
# Renderable.prototype.data - Children override this function to pass data into the render function.
#
# @return {object} template variables
###
Renderable::data = ->
merge({ id: @id }, @model)
###*
# Renderable.prototype.render - Render takes the this.data of the current object or the child, implementing the Renderable interface and renders it into the parent.
# @throws Render error if the render fails for any reason.
###
Renderable::render = ->
if !@parent
throw 'You cannot use render without a parent, use renderedString instead'
#Get the rendered string
string = @template(@data())
#Create a doc fragment to put the template in
frag = document.createDocumentFragment()
tmp = document.createElement('body')
child = undefined
#Add the template string to the tmp body
tmp.innerHTML = string
#The child is now the rendered template as a dom HTMLElement object
child = tmp.firstChild
#The child id
child.id = @id
#add the rendered template to the fragment
frag.appendChild child
#Delete the tmp body
tmp = null
if @rendered
#Replace the this.element with the fragment.
@element.parentNode.replaceChild frag, @element
else
#Add the fragment which is now the rendered template into the real dom
@parent.appendChild frag
#Set the this.element as our newly rendered element
@element = document.getElementById(@id)
#Take out the frag so it can be garbage collected.
frag = null
#Rendered state
@rendered = true
Renderable::renderedString = ->
#Get the rendered string
string = @template(@data())
@rendered = true
return string
###*
# Renderable.prototype.remove - removes the rendered template element.
###
Renderable::remove = ->
if @rendered
@parent.removeChild @element
@rendered = false
return
#@exports Renderable
module.exports = Renderable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment