Created
October 7, 2014 16:48
-
-
Save TSMMark/2addf47a9f4365468a03 to your computer and use it in GitHub Desktop.
Demplate
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
var $ = require("jQuery") | |
, Delegator | |
; | |
Delegator = function () { | |
this.$el = $("<p/>"); | |
} | |
// Add a function to the object that delegates to a property on the same object. | |
// | |
// @param obj [Object] - the object to add the function to. | |
// @param functionName [String] - the name of the function to delegate. | |
// @param delegateToPropName [String] - the name of the property on the object to delegate to. | |
// | |
// @return objFunction [Function] - the function that was created. | |
Delegator.delegate = function (obj, functionName, delegateToPropName) { | |
var objFunction = function () { | |
var delegateTo = this[delegateToPropName]; | |
return delegateTo[functionName].apply(delegateTo, arguments); | |
} | |
return obj[functionName] = objFunction; | |
} | |
// Add basic event functions to an object. | |
// functions added: `on` `off` `trigger` | |
// | |
// @param obj [Object] - the object to add the functions to. | |
// @param delegateToPropName [String] - the name of the property on the object to delegate to. | |
// | |
// Example use: | |
// Delegator.extendEventDelegation(MyClass.prototype, "delegator"); | |
Delegator.extendEventDelegation = function (obj, delegateToPropName) { | |
// Listen for an event. | |
Delegator.delegate(obj, "on", delegateToPropName); | |
// Stop listening for an event. | |
Delegator.delegate(obj, "off", delegateToPropName); | |
// Trigger an event. | |
Delegator.delegate(obj, "trigger", delegateToPropName); | |
} | |
// Delegate event functions to $el. | |
Delegator.extendEventDelegation(Delegator.prototype, "$el"); | |
module.exports = Delegator; |
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
var $ = require("jQuery") | |
, template = require("../template") | |
, Delegator = require("../Delegator") | |
, Model = require("./Model") | |
, Demplate | |
; | |
// Demplate: Data-Dependent Template | |
// @param el [Selector] - the element to render the template into | |
// @param templateID [String] - the ID of the script element with the template data | |
// @param options [Object] - key/value object of options | |
// @option data [Object] - the data to pass to the model | |
// @option model [Model] - the demplate Model | |
Demplate = function (el, templateID, options) { | |
options = (options || {}); | |
this.$el = $(el); | |
this.templateID = templateID; | |
this.options = options; | |
this.model = (options.model || new Model(options.data || {})); | |
this.currentContent = undefined; | |
this.bindings = []; | |
this.bindListeners(); | |
} | |
// Listen for key events. | |
// Events: | |
// render - triggered after new content is rendered. | |
// teardown - triggered before render if any rendered content already existed. | |
Delegator.delegate(Demplate.prototype, "on", "$el"); | |
// Set the value of a key from the model and trigger a render. | |
Delegator.delegate(Demplate.prototype, "set", "model"); | |
// Get the value of a key from the model. | |
Delegator.delegate(Demplate.prototype, "get", "model"); | |
// Register an event which will be bound to matching elements after content is rendered. | |
// Events will be automatically unbound on tearddown to avoid rogue listeners. | |
// | |
// @param selector [String] | |
// @param eventName [String] | |
// @param fn [callback] | |
Demplate.prototype.bind = function (selector, eventName, fn) { | |
this.bindings.push([selector, eventName, fn]); | |
} | |
Demplate.prototype.render = function () { | |
var content = template(this.templateID, this.model.data); | |
this.setContent(content); | |
} | |
Demplate.prototype.clear = function () { | |
this.setContent(""); | |
} | |
Demplate.prototype.setContent = function (content) { | |
if (this.currentContent) { | |
this._onTeardown(); | |
this.$el.trigger("teardown", [this.$el]); | |
} | |
this.currentContent = content; | |
this.$el.html(content); | |
this._onRender(); | |
this.$el.trigger("render", [this.$el]); | |
} | |
// For each binding, setup a listener. | |
Demplate.prototype._onRender = function () { | |
var self = this | |
, $el, eventName, fn; | |
$.each(self.bindings, function (_, data) { | |
$el = self.$el.find(data[0]); | |
eventName = data[1]; | |
fn = data[2]; | |
$el.on(eventName, fn); | |
}); | |
} | |
// Remove each binding listener. | |
Demplate.prototype._onTeardown = function () { | |
var self = this | |
, $el, eventName, fn; | |
$.each(self.bindings, function (_, data) { | |
$el = self.$el.find(data[0]); | |
eventName = data[1]; | |
fn = data[2]; | |
$el.off(eventName, fn); | |
}); | |
} | |
Demplate.prototype.bindListeners = function () { | |
var self = this; | |
self.model.on("change", function (event, key, value) { | |
self.render(); | |
}); | |
} | |
module.exports = Demplate; |
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
var $ = require("jQuery") | |
, Delegator = require("../Delegator") | |
, Model | |
; | |
// TODO: Store default so that it may be reset | |
Model = function (data) { | |
this.data = (data || {}); | |
this.delegator = new Delegator(); | |
} | |
// Set a single attribute or multiple attributes and trigger the "change" event. | |
Model.prototype.set = function () { | |
var attributes, key, value; | |
if (arguments.length == 1) { | |
attributes = arguments[0]; | |
this._setMultiple(attributes); | |
} | |
else { | |
key = arguments[0]; | |
value = arguments[1]; | |
this._setSingle(key, value); | |
} | |
this.delegator.trigger("change", [key, value]); | |
} | |
Model.prototype.get = function (key) { | |
return this.data[key]; | |
} | |
Model.prototype._setSingle = function (key, value) { | |
this.data[key] = value; | |
} | |
Model.prototype._setMultiple = function (attributes) { | |
var self = this; | |
$.each(attributes, function (key, value) { | |
self._setSingle(key, value); | |
}); | |
} | |
Delegator.extendEventDelegation(Model.prototype, "delegator"); | |
module.exports = Model; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment