Fetching contributors…
Cannot retrieve contributors at this time
126 lines (100 sloc) 4.43 KB


Controllers are where the business [logic] happens. They ask models for data, pass it along to views, and start up other controllers as children.

There are two templates for controllers you can begin with, BaseController and HtmlController, or you can write your own.

At the heart of the system, controllers are event emitters listening to Sauron.controller(name).on().start(startFn); and similarly for stop.


The BaseController function expects the following input

 * Constructor function for general purpose controller
 * @param {Object} params Parameters for configuring the controller
 * @param {String} Name of controller (used for Sauron)
 * @param {Function} [params.start] Function to run when the controller is started via Sauron
 * @param {Function} [params.stop] Function to run when the controller is stopped via Sauron

BaseController takes params.start and attaches it to Sauron.controller(name).on().start(params.start);. Additionally, params.start is invoked on params so this will refer to params while inside of params.start.

Similarly, the same properties take effect for stop.


  'name': 'myBaseController',
  'start': function () {
    console.log('Starting myBaseController');
  'stop': function () {
    console.log('myBaseController stopped');

// console.log's 'Starting myBaseController'
Sauron.start().controller('myBaseController', {});

// console.log's 'myBaseController stopped'
Sauron.stop().controller('myBaseController', {});


HtmlController adds a layer on top of BaseController. The API remains the same but we require normalization from params and Sauron calls.

// The final parameter of params will **always** be a function.
params.start = function (/* arg1, arg2, ..., */ cb) {
  // The callback expects either an HTML string, HTMLElement, DocumentFragment, or jQuery collection.
  cb('<div>some content</div>');

  // The called back content is wrapped in jQuery (normalizing everything into a jQuery collection)
  // and appended to the first parameter of the Sauron call.

  // Any additional parameters to the callback are passed to the original callback (if provided).

  // Sauron.controller('main').start($main, function (data) {
  //  // Recieves any parameters after '<div>some content</div>'
  // });

// Sauron calls to HtmlControllers require an HTMLElement, DocumentFragment,
// or a jQuery collection as their first parameter.

// You can provide a callback as the last parameter which runs once the controller has been started.
Sauron.controller('main').start($body, function () {
  // Called when start is complete and content done being appended

// HtmlController strips off the first parameter
// and uses it as the $container for the called back content to be appended to.
// As a result, params.start only receives ('b', 'c', 'd', cb) as parameters.
Sauron.controller('home').start($a, 'b', 'c', 'd', cb);
// The final parameter of params will **always** be a function.
params.stop = function (/* arg1, arg2, ..., */ cb) {
  // Callback when done

// You **must** call this if you manually specify a params.stop.

// When params.stop is called (even if you don't specify it), $container will be emptied
// and the callback (if provided) will be run.
Sauron.controller('main').stop(function () {
  // Called when stop is complete and content is removed

The reason for the stripping of the $container and $html from the callback is to enforce modularization of controllers at the framework level. It prevents any sneaky tricks/introspection between children and parents.


  'name': 'myHtmlController',
  'start': function (data, cb) {
    var html = '<div>' + data.val + '</div>';
  'stop': function (data, cb) {

// Start the controller on body
Sauron.start('myHtmlController').controller(document.body, {'val': 'Hello World!'}, function () {
  document.body.innerHTML; // <div>Hello World!</div>

  // Stop the controller
  Sauron.stop('myHtmlController').stop('Goodbye.', function () {
    // console contains 'Goodbye.'
    document.body.innerHTML; // empty string

Return to README