Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the domReady requireJS plugin correctly

Here is my main.js before using domReady:

require.config({
  paths : {
      loader : 'libs/backbone/loader',
      jQuery : 'libs/jquery/jquery-module',
      Underscore : 'libs/underscore/underscore-module',
      Backbone : 'libs/backbone/backbone-module',
      templates : '../Templates'
  }
});

require([ 'app' ], function(app) {
  app.initialize();
});

And app.js:

define([ 'jQuery', 'Underscore', 'Backbone', 'router',
    'services/Initializers/MainFrameInitializer',
    'services/Initializers/FlowsViewsInitializer',
    'services/Initializers/EditModuleInitializer',
    'services/Sandboxes/ModulesNavigationSandbox',
    'services/Sandboxes/ApplicationStateSandbox', 'DataModel/Constants' ],
    function($, _, Backbone, Router, MainFrameInitializer,
        FlowsViewsInitializer, EditModuleInitializer, ModulesNavigationSandbox,
        ApplicationStateSandbox, Constants) {
      var initialize = function() {
        // Pass in our Router module and call it's initialize function
        MainFrameInitializer.initialize();
        FlowsViewsInitializer.initialize();
        EditModuleInitializer.initialize();
        ApplicationStateSandbox.startCheckStatus();
        ModulesNavigationSandbox.navigate(Constants.Modules.Home);
        // Router.initialize();
      };

      return {
        initialize : initialize
      };
    });

All works fine until I optimize the project. I have figured out, that the script starts to run before the DOM is ready, something that was not true before the optimization. Anyway, I wish to use the domReady plugin to make sure the DOM is loaded first.

But, apparently, I have no idea how to do it correctly. Here is the new version of main.js:

require.config({
  paths : {
      loader : 'libs/backbone/loader',
      jQuery : 'libs/jquery/jquery-module',
      Underscore : 'libs/underscore/underscore-module',
      Backbone : 'libs/backbone/backbone-module',
      templates : '../Templates'
  }
});

require([ 'domReady', 'app' ], function(domReady, app) {
  domReady(app.initialize);
});

Very neat and very wrong, because app is loaded in parallel with domReady before the DOM is ready.

How do I fix it?

Thanks.

EDIT

I think I have understood our problem. The constructor functions of the app dependencies should not run any DOM dependent code. They should just return functions, capturing the DOM dependent logic. That logic should be executed from app.initialize, which is guaranteed to be run when the DOM is ready.

like image 262
mark Avatar asked Dec 03 '22 05:12

mark


2 Answers

Perhaps I am missing something, but wouldn't you make your life a lot easier by doing:

require(['jQuery', 'app' ], function(jQuery, app) {
  jQuery(function ($) {
    app.initialize();
  });
});

in your main.js?

like image 176
ggozad Avatar answered Dec 21 '22 18:12

ggozad


By requiring the app from inside the domReady callback function, you should be able to require the domReady module, and then the app module synchronously.

define(['require', 'domReady'], function(require, domReady) {
  domReady(function() {
    require(['app'], function(app) {
      app.initialize();
    });
  });
});
like image 30
brent Avatar answered Dec 21 '22 18:12

brent