如何在Ruby on Rails中创建项目范围内可用的javascript函数?

我在我的application.js中放了以下函数:

function test() { alert("See Me") } 

教室/ _new_small.html.haml:

 :javascript alert('test'); test(); 

在我的application.html.haml中,我使用以下内容:

 = javascript_include_tag 'application' 

我的firebug控制台中的test is not defined错误。 测试函数是不是应该在项目范围内可用,因为它在application.js文件中? 谢谢

编辑:我正在通过javascript渲染页面。 这会影响它吗?

 $('#test_container').html(" 'classrooms/new_small') %>"); 

假设您正在使用资产管道和coffeescript: 不要在application.js中编写代码

为了保持干净的结构,在app/assets/javascripts创建一个文件夹(例如: application

然后在你的application.js要求它

 //= require jquery //= require jquery_ujs //= require_tree ./application 

创建一个咖啡文件(例如: app/assets/javascripts/application/my_feature.js.coffee

 @test = -> alert('Hello world') 

咖啡输出:

 (function() { this.test = function() { return alert('Hello world'); }; }).call(this); 

最好使用命名空间:

 @myGreatFeature = test: -> alert('Hello world') 

或者根据coffeescript FAQ,你可以写

 namespace = (target, name, block) -> [target, name, block] = [(if typeof exports isnt 'undefined' then exports else window), arguments...] if arguments.length < 3 top = target target = target[item] or= {} for item in name.split '.' block target, top namespace 'myGreatFeature', (exports) -> exports.test = -> alert('Hello world') 

然后你可以到处调用myGreatFeature.test()

简单的解决方案,删除escape_javascript ,但它很危险,看看为什么escape_javascript在渲染部分之前? 。 目前你想执行

 $('#test_container').html(" 

转换成

 $('#test_container').html(" 

我该如何解决这个问题?

我将在app / assets / javascripts /中包含project_wide.js,然后告诉application.js包含我的文件。

 //= require project_wide 

一定要把上面的行放在后面

 //= require jquery //= require jquery_ujs 

现在,无论我放在app/assets/javascripts/project_wide.js它都会无耻地出现在整个项目中, 除了public/文件夹中的文件 。 在这个文件中,我将把我想要执行的所有内容。

遵循惯例

目前,您正在classrooms/_new_small.html.haml直接添加javascript,这是不常见的。 大多数情况下,rails开发人员将这些东西放在assets/javascripts/*.js或在视图中调用content_for :javascript_custom块,这是通过yield :javascript_custom在布局文件中添加的yield :javascript_custom

我试了一下没有问题。 这是我如何做到的。

// application.js

 var test=function(){ alert("hello"); } 

//在一个视图中,无论哪一个,我都有一个content_for:additional_javascripts

 <% content_for :additional_javascripts do %> <%= javascript_tag do %> test(); <% end %> <% end %> 

//在应用程序布局中

 <%= javascript_include_tag "application" %> <%= yeild(:additional_javascripts) %> 

此外,如果我想稍后动态提醒它,我可以将它附加到页面然后调用它,或者将它放在点击监听器或其他东西中。

我喜欢语法var functionName = function(){…},因为它正确地限定了方法。 此外,由于javascripts通过资产管道编译的方式,添加; 在每条执行行的末尾非常重要。

就动态加载脚本并从页面中的任何位置调用脚本而言,这对我也有用:

 $("#click_me").live("click", function(){ $("").text("test();").appendTo("body"); }); 

在页面中我有一个简单的链接。

 click 

你可能在想这条线

 = javascript_include_tag "application" 

而不是

 = stylesheet_link_tag 'application', :media => 'all' 

如果缺少前者,则不会包含您的javascript。

尝试使用:

 <%= javascript_include_tag :all %> 

在您的application.html.erb文件中

我注意到你的函数test()是缩进的,这表明它是嵌套的。 如果在另一个函数的范围内定义一个函数,它将无法在其外部使用。

例如,这应该工作,使用jQuery:

 function test() { /* do something */ } // another file or inline script $(function() { test(); }); 

但这不会

 (function() { function test() {} })(); // another file test(); // undefined 

将所有这些javascript函数放在application.js文件中,并在布局文件的head标记中包含<%= javascript_include_tag 'application' %>