Skip to content

Instantly share code, notes, and snippets.

@DaveGoosem
Last active August 4, 2023 05:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DaveGoosem/af551955475ddceb842e to your computer and use it in GitHub Desktop.
Save DaveGoosem/af551955475ddceb842e to your computer and use it in GitHub Desktop.
JavaScript Module Model base. Pinched from Simon here: https://gist.github.com/captainclam/3290833
/*!
* ProjectName SomeModule
* @requires jQuery v1.7.2+
* @requires Underscore v1.3.3+
*
* This comment block is here to encourage you to properly document your modules
* USE IT!
* Particularly if it has odd dependencies they should be listed.
*/
// Semicolon for minification/semicolon-insertion bug
// Anonymous function to namespace jQuery and protect global scope (see also final line)
;(function($) {
// Add Module to Project Namespace. || prevents double instantiation (Singleton?)
// Note ProjectName.BaseModule is like a "factory" that will initialise our module for us
window.ProjectName.SomeModule = window.ProjectName.SomeModule || window.ProjectName.BaseModule(function() {
// Private variables go here. Privacy is acheived in Javascript via closures
// $el is convention for "this module's element"
// Note we can not use jQuery here because it is not docready yet (see init() below)
// $varName convention says this variable is a jQuery object
var $el;
// _underscore prefix convention says this is a private variable
// Store reference to this module for events where 'this' context is altered by jQuery
var _self;
// Again, underscore prefix indicates private var.
// Note it is purely coincidence that it's an "underscore js" template
var _template = _.template('<div><%= name %></div>');
// This one is like a model/collection
var _people = [
{ name: 'Fry' },
{ name: 'Bender' },
{ name: 'Leela' }
];
var _currentPerson = 0;
// This is a private FUNCTION. Note the public can not see this.
var _getCurrentPerson() {
return _people[_currentPerson];
}
return {
// Init gets called on docready by BaseModule
init: function() {
_self = this; // see declaration comment above
$el = $('#some-module'); // Assign value to $el here because init is called on docready
this.attachEvents(); // attachEvents is purely convention, nothing special
this.render(); // render is purely convention, nothing special
},
// This renders our private model using our private template
render: function() {
var person = _getCurrentPerson();
var html = _template(person);
$el.html(html);
},
// This monitors our module's element ($el) for events
attachEvents: function() {
$el.on('click', '.some-link', this.events.clickSomeLink);
$el.on('change', '.some-input', this.events.changeSomeInput);
},
// Our event handlers are namespaced into an "events" object
// Note each event has an event argument 'e'
events: {
clickSomeLink: function(e) {
e.preventDefault();
console.log('Some link has been clicked');
// Note here 'this' refers to the clicked element
// But '_self' refers to the module, still
},
changeSomeInput: function(e) {
console.log('Some input has been changed');
}
},
// This is an example of "revealing module" pattern
// We are exposing a private variable to the public
people: _people
// Other public methods or members can go here
}
}()); // Note the immediately-invoked-function-expression (google it) that acheives a closure
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment