如何正确使用domReady requireJS插件

4

这是在使用domReady之前的我的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([ 'app' ], function(app) {
  app.initialize();
});

并且 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
      };
    });

在我优化项目之前,一切都正常。我已经发现,在优化之前脚本开始运行,而DOM还没有准备好,这在优化之前是不正确的。无论如何,我希望使用domReady插件来确保首先加载DOM。

但是,显然,我不知道如何正确地做到这一点。这是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);
});

非常整洁,但是有问题,因为在DOM准备好之前,appdomReady同时加载。

我该如何解决这个问题?

谢谢。

编辑

我认为我已经理解了我们的问题。 app依赖项的构造函数不应运行任何依赖于DOM的代码。它们只应返回函数,捕获依赖于DOM的逻辑。该逻辑应从app.initialize执行,这保证在DOM准备就绪时运行。


为什么同时加载 domReadyapp 是错误的?只有在 DOM 准备好时才会实际调用 app 中的代码。或者我误解了吗? - Paul Grime
有可能是我误解了这些东西的工作原理。加载app涉及到加载所有应用程序的依赖项(而且有相当多),然后调用这些依赖项并将结果传递给应用程序工厂方法,该方法返回app本身。如果我理解正确,app的依赖关系与domReady同时执行,这意味着它们可能在DOM完全加载之前运行。 - mark
除非你传递给 define() 的工厂函数实际运行代码,否则没有任何东西会运行。通常,工厂函数只是创建一个对象,该对象包含可以在将来某个时间点调用的方法(你已经做到了这一点)。因此,即使对 define() 的调用将运行工厂函数,但只有当你想要进行真正的应用程序工作时才会执行。就像你通过将 app.initialize 传递给 domReady 函数所做的那样。在我看来,这很好。 - Paul Grime
我已经编辑了我的帖子。这是你的意思吗? - mark
3个回答

7
也许我有所遗漏,但如果您这样做,会使您的生活变得更加轻松:
require(['jQuery', 'app' ], function(jQuery, app) {
  jQuery(function ($) {
    app.initialize();
  });
});

在你的main.js中吗?

我们正在使用jQuery,但你不能直接像那样使用它,因为jQuery在requireJS的意义上并没有定义自己作为一个模块。它需要先进行一些准备工作,我们已经完成了这些工作。另外,请注意app确实依赖于jQuery,它是其第一个依赖项。 - mark
1
自从 jQuery 版本在 1.7 左右(iirc)开始,它就符合 AMD 规范了。如果你依赖于之前的某个版本,你可以随时使用加载器。你的应用程序和主要文件都依赖于 jQuery,这不会违反任何规定(jQuery仍然只会被加载一次),但这将使您无需添加另一个插件。 - ggozad
好的,但是这个方案仍然要求app依赖的模块的工厂方法不要操作DOM,因为app的依赖关系会与jQuery的加载并行解析和调用。原来的问题仍然存在。但是我似乎已经想出了问题所在 - 请参见我帖子的编辑部分。 - mark
1
没有什么要求你不使用jQuery或操作DOM。这只是纯简单的js。如果您想使用它的ready()函数,将jQuery作为依赖项添加到您的主文件中是可以的。 - ggozad
@widged:搜索jQuery + AMD。Require.js只是更多AMD加载器之一,它们都试图遵循AMD加载的CommonJS标准。http://bugs.jquery.com/ticket/7102 - John Korsnes
显示剩余2条评论

7

通过在domReady回调函数中要求应用程序,您应该能够同步地请求domReady模块,然后是应用程序模块。

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

3
如果你按照文档:http://requirejs.org/docs/jquery.html,你将被邀请在文档头部嵌入一个 require-jquery 库:
<script data-main="main" src="libs/require-jquery.js"></script>

然而,如果查看提供在GitHub上的示例源代码,您会发现'require-jquery.js'是通过将require库文件和jquery库文件简单地连接起来生成的。请注意保留HTML标记。
 cat require.js jquery.js > ../jquery-require-sample/webapp/scripts/require-jquery.js

这意味着您可以用以下脚本嵌入替换头部的脚本嵌入,放在文档中的任何位置(例如放在文档底部)。
  <script src="libs/require.js"></script>
  <script src="libs/jquery-1.8.0.js"></script>
  <script>require(["main"]);</script>

因为jquery库定义自己为一个模块,包含以下内容:
  define( "jquery", [], function () { return jQuery; } );

您可以将jquery作为引用在任何脚本中使用。例如:

  require(["jquery"], function($) { }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接