We use AMD to organize our code, so we use Almond for this.
This is the dispatcher code:
define('dispatcher', ['jquery'],
function($) {
'use strict';
var components = $('[data-component]'),
modules = $('[data-modules]');
$.each(components, function(__index, component) {
var currentComponent = $(component),
options = currentComponent.data();
require(options.component);
currentComponent[options.component](options);
});
$.each(modules, function(index) {
var Module = require(modules[index]);
Module = new Module();
Module.initialize();
});
}
);
require('dispatcher');
The dispatcher will instantiate modules and execute components like a jQuery plugin, then you need to code them that way.
If you have a code like this:
<body data-modules="foo bar">
<button data-component="backToTop" data-speed="600">Back to top</button>
<div
data-modules="baz"
data-component="carousel"
data-pagination="true"
data-slides-to-show="3"
data-circular="true"></div>
</body>
The dispatcher will automatically require the modules foo
, bar
and baz
present in data-modules
. And will execute the components based on the attribute data-component
, passing other attributes as options, after require the files, this example will execute:
var Module;
Module = new Foo(); Module.initialize();
Module = new Bar(); Module.initialize();
Module = new Baz(); Module.initialize();
$('data-component="backToTop"').backToTop({
speed: 600
});
$('[data-component="carousel"]').carousel({
pagination: true,
slidesToShow: 3,
circular: true
});
Code modules like a javascript class, using a method called initialize
to start they behavior, so it will be instantiate when needed.
Why have an initialize method?
- Because constructors should not cause side effects.
define('someService', ['jquery'],
function($) {
'use strict';
function SomeService() {
this.message = 'Hello from SomeService Module';
}
SomeService.prototype.initialize = function() {
this.sayHello();
};
SomeService.prototype.sayHello = function() {
console.log(this.message);
};
return SomeService;
}
);
Code every component like a jQuery plugin, it will be dynamically executed passing the options to the plugin.
A component should always return this
.
define('backToTop', ['jquery'],
function($) {
'use strict';
$.fn.backToTop = function(options) {
var defaults = {
scrollSpeed: 400,
scrollToPosition: 0
};
var settings = $.extend({}, defaults, options);
this.on('click', function(e) {
e.preventDefault();
$('html, body').animate({
scrollTop: settings.scrollToPosition
}, settings.scrollSpeed);
});
return this;
};
}
);
Precisa ser exatamente na body o Módulo? Módulo é tipo o grupo que vai ser inserido o contexto, certo?