【问题标题】:rails 3 javascript fine coffeescript referenceerror (class) is not definedrails 3 javascript fine coffeescript referenceerror(类)未定义
【发布时间】:2012-11-03 09:44:24
【问题描述】:

RubyRogues 播客上的某个人曾经说过“学习 CoffeeScript,因为 CoffeeScript 编写的 JavaScript 比你好。”抱歉,不记得是谁说的了...

所以,我采用了一个非常简单的 WORKING javascript 函数:

togglingii.js

function pdtogglejs(id) {   $('div .partybackground').removeClass("hidden");  }

这行调用的是什么:

<a href="#" class="dctoggle" onclick="pdtogglejs('partybackground')">Read More...</a>

然后我把它转换成这个咖啡脚本: toggling.js.coffee

pdtogglecs(id) ->
   jQuery('div .partybackground').removeClass("hidden")

并更改了 html 以引用 pdtoggle*c*s 而不是 pdtoggle*j*s。

我可以在我的 application.js 文件中看到它们都很好:

(function() {

  pdtogglecs(id)(function() {
    return jQuery('div .partybackground').removeClass("hidden");
  });

}).call(this);
function pdtogglejs(id) {   $('div .partybackground').removeClass("hidden");  }
;
(function() {



}).call(this);

但是,只有纯 javascript 有效。咖啡脚本总是返回 Uncaught ReferenceError: pdtogglecs is not defined.

根据其他 stackoverflow 问题,它一定是某种命名空间错误。可能是因为 pdtogglecs 本身在函数内部的方式?但是,我尝试使用以下方法定义咖啡脚本函数:window.pdtogglecs、this.pdtogglecs、root.pdtogglecs,而咖啡脚本总是因该错误而失败。

我错过了什么??

谢谢!!

【问题讨论】:

    标签: javascript jquery ruby-on-rails-3 coffeescript


    【解决方案1】:

    你有两个问题,一个是CoffeeScript语法有点混乱,另一个是你知道的命名空间问题。

    我们将从整理您的语法混乱开始。这个:

    f(x) -> ...
    

    是这样解释的:

    f(x)(-> ...)
    

    所以当给出这个时:

    pdtogglecs(id) ->
       jQuery('div .partybackground').removeClass("hidden")
    

    CoffeeScript 认为您正在尝试将 pdtogglecs 作为函数调用,并将 id 作为参数。然后它认为 pdtogglecs(id) 返回一个函数,并且您想以 -&gt; jQuery(...) 函数作为参数调用该函数。所以它最终是这样的:

    callback = -> jQuery(...)
    returned_function = pdtogglecs(id)
    returned_function(callback)
    

    这与您的原始 JavaScript 完全不同。你想创建一个名为 pdtogglecs 的函数,它以 id 作为参数,然后运行你的 jQuery 东西:

    pdtogglecs = (id) ->
        # -----^ this is sort of important
        jQuery('div .partybackground').removeClass("hidden")
    

    您可以通过查看生成的 JavaScript 来了解发生了什么。

    命名空间问题很简单,您可能可以根据您发现的其他问题来解决这个问题。不过,为了完整起见,我会在这里处理它。

    CoffeeScript 将每个 .coffee 文件包装在一个自执行函数中以避免污染全局命名空间:

    (function() {
        // JavaScript version of your CoffeeScript goes here...
    })();
    

    该包装器将所有内容都限定为.coffee 文件。如果你想污染全局命名空间,那么你必须这样说:

    window.pdtogglecs = (id) -> ...
    

    你也可以说:

    @pdtogglecs = (id) -> ...
    

    但我更喜欢直接引用window 的明确性,这也让您不必担心解析代码时@(AKA this)是什么。

    【讨论】:

    • 哇,多么彻底的回应!非常感谢。好的,所以我想我明白了,而且我看到这个功能现在看起来更好了。但是我已经尝试了 window.pdtogglecs 和 @pdtogglecs ,但我仍然看到错误。使用 window.xml 时是否必须更改调用方式?或@?
    • @Dave: 它应该可以工作 (jsfiddle.net/ambiguous/seFRD) 除非你的 HTML 使用 pdtogglejs 并且你的 CoffeeScript 定义了 window.pdtogglecs 看到“c”和“j”不是一回事。 .
    • 好的,我会继续搞砸的。我认为您已经对我进行了足够的教育来解决这个问题!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-02
    • 2021-11-26
    • 1970-01-01
    相关资源
    最近更新 更多