Skip to content

Instantly share code, notes, and snippets.

@derekgreenberg
Created April 29, 2013 07:13
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 derekgreenberg/5480161 to your computer and use it in GitHub Desktop.
Save derekgreenberg/5480161 to your computer and use it in GitHub Desktop.
components for AMD JS app
Example of how the requirejs app is started up from a simple HTML doc.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Fun!</title>
<style type="text/css">
body {padding: 20px;}
</style>
<script id="rg_vis_widget" data-main="http://localhost:3000/assets/rg_data_visualization_widget.js" src="http://localhost:3000/assets/requirejs.min"></script>
</head>
<body>
<div class='rg_widget' data-widget='stream_fills'></div>
</body>
</html>
Here is the main function invoked by the script tag above:
/*global define*/
/*
* Description: A jQuery plugin to provide RealGravity data visualization widgets
*/
define(["jquery", "RG.Class", "RG.datavis.Control.Graph", "RG.datavis.Control.Scoreboard", "RG.datavis.Control.Daterange"], function(jQuery, RG){
/**
* jq returns the jQuery instance (with the plugin binding) from this AMD module.
*/
var jq;
(function ($, window, document, undefined) {
// Create the defaults once
var pluginName = "rgDataVisualization";
var defaults = {};
// The actual plugin constructor
function RGDataVisualization(element, options) {
this.element = element;
defaults.widget = element;
this.options = $.extend({}, defaults, options, $(element).data('options'));
this._defaults = defaults;
this._name = pluginName;
this.init();
}
RGDataVisualization.prototype = {
init: function () {
var control = $(this.element).data('control'),
self = this;
if(control !== undefined){
// if we have a data-control attr
this.load_control(this.element);
if($(this.element).data('rg_control')){
$(this.element).data('rg_control').render();
}
}
else {
// we have a panel
// iterate over child controls
$.each($('[data-control]', $(self.element)), function(){
self.load_control(this);
});
$.each($('[data-control]', $(self.element)), function(){
if($(this).data('rg_control')) {
$(this).data('rg_control').render();
}
});
}
},
load_control: function(element){
var args = $.extend({element:element}, this.options, $(element).data('options'));
switch($(element).data('control')){
case 'graph':
$(element).data('rg_control', new RG.datavis.Control.Graph(args));
break;
case 'scoreboard':
$(element).data('rg_control', new RG.datavis.Control.Scoreboard(args));
break;
case 'daterange':
$(element).data('rg_control', new RG.datavis.Control.Daterange(args));
break;
default:
$(element).append("<span>Invalid control type specified</span>");
break;
}
}
};
// A really lightweight plugin wrapper around the constructor,
// preventing against multiple instantiations
$.fn[pluginName] = function (options) {
return this.each(function () {
if (!$.data(this, "plugin_" + pluginName)) {
$.data(this, "plugin_" + pluginName, new RGDataVisualization(this, options));
}
});
};
// assign this jQuery instance to the AMD return value
jq = $;
}(jQuery, window, document));
return jq;
});
Jasmine helpers that load AMD modules. Add to spec/javascripts/helpers/SpecHelper.js
var aIt, aBeforeEach;
/**
* Asynchronous version of Jasmine's 'it' function
* Use it like 'it', but pass in an array of dependencies (i.e. AMD modules) by module name
* If a module returns a value, reference it in the testFn parameter list
* @param {String} description same as the description text passed in to 'it'
* @param {Array} modules AMD module dependencies for the 'it' block test.
* @param {Function} testFn test to execute within the context of the values returned from the array of modules
*/
aIt = function(description, modules, testFn) {
it(description, function() {
var readyModules;
readyModules = [];
waitsFor(function() {
requirejs(modules, function() {
readyModules = arguments;
});
return readyModules.length === modules.length;
});
runs(function() {
var arrayOfModules;
arrayOfModules = Array.prototype.slice.call(readyModules);
testFn.apply(null, arrayOfModules);
});
});
};
/**
* Asynchronous version of Jasmine's 'beforeEach' function
* Use it like 'beforeEach', but pass in an array of dependencies (i.e. AMD modules) by module name
* If a module returns a value, reference it in the beforeFunction parameter list
* @param {Array} modules AMD module dependencies for the tests
* @param {Function} beforeFunction set-up function to execute before each test
*/
aBeforeEach = function(modules, beforeFunction) {
beforeEach(function(){
var readyModules;
readyModules = [];
waitsFor(function(){
requirejs(modules, function() {
readyModules = arguments;
});
return readyModules.length === modules.length;
});
runs(function() {
var arrayOfModules;
arrayOfModules = Array.prototype.slice.call(readyModules);
beforeFunction.apply(null, arrayOfModules);
});
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment