#javascript #ruby-on-rails #coffeescript
#javascript #ruby-на-рельсах #coffeescript #ruby-on-rails
Вопрос:
В моем приложении есть представления, которые ссылаются на мой application.js файл, содержащий функции, которые я использую во всем моем приложении.
Я только что установил Rails 3.1 release candidate после использования edge версии 3.1. Пока я не установил RC, у меня не было никаких проблем, но теперь я получаю эту ошибку:
Ошибка ReferenceError: не удается найти переменную: indicator_tag
indicator_tag — это функция, которую я определил в application.js . Единственное отличие, которое я замечаю в файле javascript, заключается в том, что теперь все мои функции обернуты в:
(function() { ... }).call(this);
Я так понимаю, это для определения области видимости переменной? Но может ли это помешать моим страницам использовать эти переменные? И прежде чем кто-либо спросит, я убедился, что пути javascript указаны правильно в моих тегах include.
Комментарии:
1. Вы пытаетесь сослаться на indicator_tag из файла, отличного от application.js.coffee?
2. Нет, это в application.js.coffee.
3. Не могли бы вы вставить содержимое вашего скрипта?
4. Вы пытаетесь вызвать
indicator_tag
из встроенных скриптов, на ваш взгляд?5. Не встроенный, а отдельный файл javascript только для этой страницы. Тег include для этого файла находится ниже тега для application.js . Вот содержимое этого файла pastie.org/1957528
Ответ №1:
По умолчанию каждый файл CoffeeScript компилируется в замыкание. Вы не сможете взаимодействовать с функциями из другого файла, если не экспортируете их в глобальную переменную. Я бы рекомендовал сделать что-то вроде этого:
Поверх каждого файла coffeescript добавьте строку типа
window.Application ||= {}
Это гарантирует постоянное присутствие приложения с глобальным именем.
Теперь для каждой функции, которую вам потребуется вызвать из другого файла, определите их как
Application.indicator_tag = (el) ->
...
и вызываем их с помощью
Application.indicator_tag(params)
Комментарии:
1. Ответ Догберта правильный. (Обратите внимание, что в этом случае вы также могли бы использовать
this
/@
для экспорта переменных как глобальных, например@indicator_id = ...
, поскольку оболочка CoffeeScript вызывается в глобальном контексте). Причина, по которой вы столкнулись с этим только сейчас, заключается в том, что более ранние версии Rails 3.1 отключили оболочку CoffeeScript. Это поведение было классифицировано как ошибка и исправлено для RC1: github.com/rails/rails/issues/11252. Я бы дал вам 10 секунд, если бы мог, за этот ответ. Большое спасибо.
Ответ №2:
Решение Догберта — отличный вариант, если у вас очень сложный сервер JS. Однако есть гораздо более простое решение, если у вас есть только несколько функций, с которыми вы работаете. Просто добавьте их непосредственно в объект window, вот так:
window.indicator_tag = (el) ->
...
Тогда вы сможете использовать свои функции из любого места без необходимости оборачивать их в другой объект.
Комментарии:
1. Что плохого в том, чтобы обернуть их в другой объект? Если вы хотите избежать ввода «Application», назовите это «App». Контекст часто действительно полезен в любом случае, когда вы просто читаете код…
2. И я бы добавил, чем это «окно». это то же самое, что «@», не так ли?