Created
June 8, 2015 05:33
-
-
Save austbot/96a78a49fd607fa83b5b to your computer and use it in GitHub Desktop.
Renderable
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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