如何在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("<%= escape_javascript(render :partial => '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("<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

我试过了,没有任何问题。我是这样做的。

//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(){…},因为它正确地限定了方法的作用域。此外,由于javascript是通过资产管道编译的,所以添加;

这也为我工作,只要动态加载脚本,并从页面的任何地方调用它:

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

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

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

你可能想到的是

这一行
= javascript_include_tag "application"

而不是

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

尝试使用:

<%= 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文件中包含<%= javascript_include_tag 'application' %>头部标签的布局文件

最新更新