Как вы создаете функции javascript, доступные в масштабе всего проекта в Ruby on Rails?

Я поместил следующую функцию в свой application.js:

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

классы/_new_small.html.haml:

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

В моем приложении application.html.haml я использую следующее:

= javascript_include_tag 'application'

Я получаю ошибку test is not defined в моей консоли firebug. Является ли функция тестирования не доступной для всего проекта, потому что ее в файле application.js? Благодаря

edit: Я просматриваю страницу через javascript. Это повлияет на это?

$('#test_container').html("<%= escape_javascript(render :partial => 'classrooms/new_small') %>");

Ответы

Ответ 1

Предполагая, что вы используете конвейер ресурсов и 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, вы можете написать

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() всюду

Ответ 2

Вероятно, вы думаете о линии

= javascript_include_tag "application"

а не

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

Если первый отсутствует, ваш javascript не будет включен.

Ответ 3

Попробуйте использовать:

<%= javascript_include_tag :all %>

в вашем application.html.erb файле

Ответ 4

Я заметил, что ваша функция test() имеет отступы, что предполагает, что она вложена. Если вы определяете функцию в области действия другой функции, она не будет доступна за ее пределами.

Например, это должно работать, используя jQuery:

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

// another file or inline script

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

Но это не будет

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

// another file

test(); // undefined

Ответ 5

Простое решение, удалите 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");

Как решить эту проблему?

i будет включать project_wide.js в app/assets/javascripts/, а затем сообщите application.js о включении моего файла.

//= require project_wide

Обязательно поместите указанную выше строку после

//= require jquery
//= require jquery_ujs

Теперь, что бы я ни разместил в app/assets/javascripts/project_wide.js, он будет бесстыдно появляться в целом проекте , кроме файлов, находящихся в папке public/. В этом файле я поставлю все, что хочу выполнить.

Следуйте обычной практике

В настоящее время вы добавляете javascript непосредственно внутри classrooms/_new_small.html.haml, что является необычным. В основном разработчик rails помещал такие вещи в assets/javascripts/*.js или вызывал content_for :javascript_custom блок в представлениях, который добавляется в файл макета yield :javascript_custom

Ответ 6

Я пробовал это без проблем. Вот как я это сделал.

//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 скомпилированы через конвейер активов, добавив; в конце каждой выполненной строки очень важно.

Это также помогало мне загружать script динамически и вызывать его из любой точки на странице:

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

И на странице у меня была простая ссылка.

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

Ответ 7

поместите все эти функции javascript в файл application.js и включить <%= javascript_include_tag 'application' %> в тег заголовка вашего файла макета