I'm using requirejs and have an app.js
that pulls in framework.js
and initializes it and passes in settings and modules with their own settings. Problem is $('[data-navigation]').navigation();
is triggering before the navigation
module, which is a jQuery plugin, is ready. If I add around a 500ms delay it works.
require(['jquery-private', 'framework', 'navigation'],
function($, framework, navigation) {
//==========
// Initialize the framework core.
//==========
var core = framework.init({
// Core settings.
namespace: '',
// Initialize modules.
modules: {
navigation: {
openClass: 'open',
},
},
});
//==========
// App logic.
//==========
$('[data-navigation]').navigation();
});
Here is how the modules are initialized. I think the problem is happning with this require([moduleName], function(module) {}
running while the script continues on.
define(['jquery', 'matchmedia'], function($) {
//==========
// Core initialization object.
//==========
var init = function(customOptions) {
//==========
// Logic
//==========
//==========
// Load a module with it's custom options.
//==========
function initModule(module, customOptions, coreObject) {
// Get the previously defined module or the path to load it.
var moduleName = (require.defined(module)) ? module : config.modulesDir + '/' + module;
// Initialize the module.
require([moduleName], function(module) {
var returnObject = module.init(customOptions, coreObject);
// Add to the loaded modules if not already present.
if (settings.modules.indexOf(moduleName) < 0) {
settings.modules.push(moduleName);
settings.m[moduleName] = returnObject;
}
});
return settings.m[moduleName];
}
//==========
// Logic
//==========
//==========
// Build the core object.
//==========
var core = {
// Properties.
// Methods.
}
//==========
// Load the defined modules.
//==========
$.each(config.modules, function(index, value) {
initModule(index, value, core);
});
//==========
// Return the core object.
//==========
return core;
}
//==========
// Return the initialization object.
//==========
return {
init: init
}
});
I've been at this for a while now. I'm pretty sure there is a solution, but I can't seem to wrap my head around it. Any guidance is appreciated.
Here is a good chunk of the navigation module code if it helps.
define(['jquery'], function($) {
//==========
// Module initialization object.
//==========
var init = function(customOptions, core) {
// Ensure customOptions is an object.
var customOptions = typeof customOptions !== 'undefined' ? customOptions : {};
// Get the custom selector or the modules default.
var selector = typeof customOptions.selector !== 'undefined' ? customOptions.selector : '[' + core.space('data-navigation') + ']';
//==========
// Build the jQuery plugin.
//==========
$.fn.navigation = function(options) {
//==========
// Plugin code.
//==========
}
//==========
// Initialize the plugin.
//
// RUNNING THE PLUGIN FROM HERE DOES WORK, BUT I NEED IT TO WORK FROM THE APP.JS TOO!
//
//==========
$(function() {
if ($(selector).length > 0) {
$(selector).navigation(customOptions);
}
});
//==========
// Return object for core.m.[module]
//==========
return {};
}
//==========
// Return the module initialization object.
//==========
return {
init: init
}
});
In the specific sample above, the solution was to use
module = require('moduleName');
instead ofrequire([moduleName], function(module) {}
. Here is the new initModule function;Only problem is this only works if my
app.js
pulls in the module in it'srequire()
statement. It will still hit the same error if the module is not compiled into the main script file and instead is loaded dynamically. My solution was to just send a message to the console saying to userequire([moduleName], function(module) { /* Use module here. */ });
if the module isn't compile into the main script. I'm still seeking a better solution, but it's starting to seem this is inherit in dynamically loading modules.