2012-02-20 48 views
4

这是我main.js:如何使用domready中requireJS使用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(); 
}); 

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

一切工作正常,直到我optimize项目。我已经发现,在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); 
}); 

非常整齐,非常错误的,因为app装入平行domReady之前DOM已准备就绪。

我该如何解决?

谢谢。

编辑

我想我已经明白我们的问题。 app依赖项的构造函数不应该运行任何与DOM相关的代码。他们应该只是返回函数,捕获DOM依赖的逻辑。该逻辑应该从app.initialize开始执行,当DOM准备就绪时,这将保证运行。

+0

为什么'domReady'和'app'并行加载错了?当DOM准备就绪时,您只能从'app'调用代码。或者我误解了? – 2012-02-20 15:07:35

+0

这可能是我误解了这些东西的工作原理。加载'app'涉及加载所有的应用程序依赖关系(并且有很多),然后调用这些依赖关系,并将结果传递给应用程序工厂方法,该方法返回'app'本身。如果我理解正确,'app'的依赖与'domReady'并行执行,这意味着它们可以在DOM完全加载之前运行。 – mark 2012-02-20 15:13:49

+0

没有*运行*除非您传递给define()的工厂函数实际运行代码。通常情况下,工厂函数只是创建一个对象,其方法可以在将来的某个时刻调用*(您已经这样做了)。所以即使调用'define()'将会运行工厂函数,你只需要* real * app就可以工作。就像通过将'app.initialize'传递给'domReady'函数一样。对我来说似乎很好。 – 2012-02-20 15:29:30

回答

7

也许我失去了一些东西,但你不会让你的生活变得更加简单做:

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

main.js

+0

我们正在使用jQuery,但是你不能像以前那样使用它,因为jQuery没有将它自己定义为一个模块,它的requireJS意义上说它是。它首先需要一些准备工作,我们会这样做。另外,请注意'app'确实依赖于'jQuery',这是它的第一个依赖。 – mark 2012-02-21 07:16:46

+1

自iirc 1.7起,jQuery *符合AMD标准。如果你依赖于以前的版本,你总是可以使用加载器。你的应用程序和主要两个都取决于jQuery不会违反任何东西(jQuery仍然会加载一次),但它可以让你不添加另一个插件。 – ggozad 2012-02-21 07:20:53

+0

好的,但是这个方案仍然要求'app'所依赖的模块的工厂方法不会操纵DOM,因为'app'依赖被解析并且与jQuery的加载并行地被调用。原始问题仍然存在。但似乎我已经弄清楚这里有什么问题 - 请参阅我的帖子的编辑。 – mark 2012-02-21 11:11:14

3

如果按照在DOC:http://requirejs.org/docs/jquery.html,你将被邀请在文档的头部嵌入要求,jQuery库:

<script data-main="main" src="libs/require-jquery.js"></script> 

但是,如果你看看源的例子,在github提供,你会看到“要求-的jquery.js”被需要的lib文件和jQuery的库文件的简单连接,产生:

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的LIB将自己定义为一个模块:

define("jquery", [], function() { return jQuery; }); 

可以随后使用jquery在任何脚本的需要参考。例如:

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

通过要求从domready中的回调函数里面的应用程序,你应该能够要求domready中模块,然后将应用程序模块同步。

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