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

时间:2012-12-31 00:51:19

标签: ruby-on-rails ruby-on-rails-3

我在我的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("<%= escape_javascript(render :partial => 'classrooms/new_small') %>");

7 个答案:

答案 0 :(得分:26)

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

为了保持结构清洁,请在application

中创建一个文件夹(例如:app/assets/javascripts

然后在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()

答案 1 :(得分:1)

简单解决方案,删除escape_javascript,但危险请参阅Why escape_javascript before rendering a partial?。 目前你想执行

$('#test_container').html("<script>
//<![CDATA[
 alert('test');
 test();
//]]>
</script>

转换为

$('#test_container').html("<script>\n  //<![CDATA[\n    alert(\'test\');\n    test();\n  //]]>\n<\/script>\n");

我如何解决这个问题?

我将在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

中添加到布局文件中

答案 2 :(得分:1)

我没有遇到任何问题。我就是这样做的。

// 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(){
  $("<script />").text("test();").appendTo("body");
});

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

<a href="#" id="click_me">click</a>

答案 3 :(得分:0)

你可能正在考虑这条线

= javascript_include_tag "application"

而不是

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

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

答案 4 :(得分:0)

尝试使用:

<%= javascript_include_tag :all %>

在您的application.html.erb文件中

答案 5 :(得分:0)

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

例如,这应该可以使用jQuery:

function test() { /* do something */ }

// another file or inline script

$(function() {
   test();
});

但这不会

(function() {
   function test() {}
})();

// another file

test(); // undefined

答案 6 :(得分:0)

将所有这些javascript函数放在 application.js 文件中 在布局文件的 head tag 中加入<%= javascript_include_tag 'application' %>