Coffeescript,Backbone和加载顺序

时间:2011-09-07 06:40:26

标签: coffeescript dependency-management

考虑这个Coffeescript类,在一个应用程序中,每个类都存在于自己的文件中。

class Manager extends Person
  title: titles["manager"]

如果在“titles”对象之前加载该文件,则会生成错误。我假设这是因为Coffeescripts安全包装器在首次加载此文件时执行“.call(this)”?

否则,如果我要延迟运行任何代码,直到整个页面完全加载($(document.ready())之后,我可以确定在任何代码实际运行之前所有的javascript文件都已完全加载。 / p>

这不会造成一些烦人的加载顺序问题,还是我没有正确地做某事?

3 个答案:

答案 0 :(得分:2)

它不能同时是订单问题包装问题。使用立即运行的函数包装内容对订单没有影响,仅适用于范围。

如果titles在另一个文件中定义,则class Manager的范围无关紧要。所以,这是一个订单问题。如何定义titles

  

如果我要延迟运行任何代码,直到整个页面完全加载($(document.ready())之后,我可以确定在任何代码实际运行之前所有的javascript文件都已完全加载。

不完全。 $(document).ready()(注意括号 - 没有document.ready函数...)延迟函数的执行,直到加载了所有页面的HTML,这并不意味着所有的JavaScript都已加载。这是个好消息:从JavaScript代码的角度来看,是否已加载其他JavaScript文件无关紧要,因为它们都是按顺序运行的。 (注意:我在这里假设您没有像在JavaScript代码中添加其他<script>标记那样做任何想法。)所以只要你有

<script src="titles.js"></script>
<script src="Manager.js"></script>

您可以放心,Manager.js只会在titles.js之后运行。

警告!依赖$(document).ready()订购JS代码是一个常见的错误,可能导致混淆!如果您的HTML看起来像这样

<script src="Manager.js"></script>
<script src="titles.js"></script>

其中titles.js创建一个名为titles的全局,Manager.js看起来像这样

$(document).ready ->
  console.log titles

然后输出有时titles有时undefined。为什么?因为the docs说,

  

如果在初始化DOM之后调用.ready(),则会立即执行传入的新处理程序。

当第一个JS文件运行时,DOM可能已经被初始化了! (实际上,如果浏览器将页面的HTML缓存,则会发生这种情况。)

所以,保持简单。只需按正确的顺序加载脚本即可。请记住,出于所有实际目的,您的脚本将由浏览器按顺序连接到一个JS文件中。

答案 1 :(得分:2)

试试CoffeeToaster:
http://github.com/serpentem/coffee-toaster

通过提供import指令(即#<<,即:

,它将完全符合您的要求。
#<< foldera/folderb/folderc/myfile

您不需要通知.coffee扩展程序,如果您习惯于以下内容,则可以打开packaging选项以设置名称空间设置:

#<< another/package/myclass
class SomeClass extends another.package.MyClass

它有一个构建系统,可以为您或几个(在调试模式下)输出单个javascript文件,以简化调试过程。

查看README和用法示例:
https://github.com/serpentem/coffee-toaster/tree/master/usage

答案 2 :(得分:0)

这确实是一个加载顺序问题,titles中的Manager在这种情况下引用了一个全局,此时未声明。如果您知道titles在其他地方全局声明,则必须手动确保首先加载脚本。是的,问题很可能与安全包装有关。但作为一个建议:这是有充分理由的。创建自己的命名空间,而不是导出到全局对象。全局对象位于this(定义时)或节点中的exports。我通常将这个单行代码放在应该可以轻松访问全局对象的脚本之上:

root = exports ? window

从那里我可以把东西放在全局对象中,比如命名空间:

root.app =
  a: 1,
  a_fun: -> 1

class root.app.Cls
   method: => 1 + 1

root.app.obj = new root.app.Cls

现在,全局对象中将有一个'app'对象,带有'class'(可以这么说)和object。

相关问题