Функции в controller.js.coffee

У меня возникли проблемы с созданием функций с помощью CoffeeScript, наверное, я что-то пропустил. Для моего контроллера пользователей я хотел бы создать проверку на стороне клиента для формы регистрации. Я думаю, что упустил что-то фундаментальное в том, как все это работает.

<%= form_for @user, :html => {:onsubmit => "return validate_signup_form();"} do |f| %>

CoffeeScript (assets/users.js.coffee):

validate_signup_form = () ->
    alert "Hi"
    return false

Ожидаемый результат:

var validate_signup_form;
validate_signup_form = function() {
  alert("Hi");
  return false;
};
validate_signup_form();

Реальный выход:

(function() {
  var validate_signup_form;
  validate_signup_form = function() {
    alert("Hi");
    return false;
  };
}).call(this);

person Emil Ahlbäck    schedule 21.06.2011    source источник
comment
Лучший подход к этому - привязка событий к полям, но если у кого-то есть решение этой конкретной проблемы, я был бы рад его услышать, возможно, оно пригодится в другой раз.   -  person Emil Ahlbäck    schedule 21.06.2011
comment
странно, онлайн-кофейный скрипт почти повторяет то, что вы ожидаете. См.: jashkenas.github.com/coffee-script.   -  person apneadiving    schedule 21.06.2011
comment
Да, что-то меняется, когда Rails включает файл. Может быть особенностью. :)   -  person Emil Ahlbäck    schedule 21.06.2011


Ответы (2)


На самом деле все работает так, как должно. Как вы можете прочитать здесь, Coffeescript заключает ваш код в анонимную функцию, чтобы предотвратить загрязнение глобального пространства имен. Если вы просто взглянете на примеры, вы можете пропустить это, но в документах четко указано:

Несмотря на то, что для ясности это опущено в этой документации, весь вывод CoffeeScript заключен в анонимную функцию: (function(){ ... })(); Эта защитная оболочка в сочетании с автоматическим созданием ключевого слова var чрезвычайно затрудняет случайное загрязнение глобального пространства имен.

Чтобы получить доступ к объекту, переменной или методу, объявленному в этой искусственной области, вам необходимо сделать его явно доступным в глобальной области, например. нравится:

window.validate_signup_form = validate_signup_form

В случае, если вы упомянули, я бы определенно использовал события для запуска метода.

Кстати: нет необходимости в пустой скобке в объявлении вашего метода foo =-> работает просто отлично.

person polarblau    schedule 21.06.2011
comment
Спасибо за разъяснения! На самом деле я только просмотрел примеры. - person Emil Ahlbäck; 21.06.2011
comment
coffeescript --bare скомпилирует код без анонимной оболочки. - person Elf Sternberg; 21.06.2011
comment
Правильно, и вот как включить --bare в Rails. Но не делай этого! И вот почему. - person Trevor Burnham; 21.06.2011

Ответ polarblau вполне правильный. Смотрите также:

Оболочка закрытия — отличный способ сохранить модульность файлов (какими они должны быть), поэтому я настоятельно не рекомендую избавляться от нее. Обратите внимание, что во внешней области ваших модулей this/@ будет window, поэтому вы можете заставить свой код работать так, как задумано, просто добавив один символ:

@validate_signup_form = ->
  alert "Hi"
  false

Вам решать, предпочитаете ли вы использовать @ или window. для определения глобальных переменных, но у стиля @ есть еще одно преимущество: если вы повторно используете свой код в приложении Node.js, он все равно будет работать. Эти объекты будут прикреплены к exports вместо window.

person Trevor Burnham    schedule 21.06.2011