Как пространство имен работает в Coffeescript и Rails?
-
24-12-2019 - |
Вопрос
Я смотрю на этот кофескрипт код из Gitlab и задаюсь вопросом, как это работает.
class Issue
constructor: ->
$('.edit-issue.inline-update input[type="submit"]').hide()
$(".issue-box .inline-update").on "change", "select", ->
$(this).submit()
$(".issue-box .inline-update").on "change", "#issue_assignee_id", ->
$(this).submit()
@Issue = Issue
Кажется, что это используется только в представлениях, связанных с проблемами, но нигде не вызывается в HTML-файлах проблем.Есть ли здесь что-то волшебное за кулисами?А также какое значение имеет @Issue = Issue
линия?
Решение
@Issue = Issue
просто публикует локальную переменную в глобальной области видимости.Это не имеет ничего общего с Ruby или Rails.Это чисто кофейная идиома.
CoffeeScript выполняется внутри оболочки, предназначенной для предотвращения создания переменных в глобальной области видимости.И в этой обертке this
(или @
) — глобальный объект.
Итак, это:
class Issue
constructor: ->
@Issue = Issue;
Компилируется примерно в этот JS:
(function() {
var Issue;
Issue = (function() {
function Issue() {}
return Issue;
})();
this.Issue = Issue;
}.call(window));
В этом JS window
становится this
, а свойства окна становятся глобальными переменными.Итак, с этого момента вам нужно только набрать Issue
в любом другом файле JS, и у вас появится конструктор задач.
Без @Issue = Issue
линия, Issue
Конструктор никогда не будет доступен вне этого кода, и ни один другой файл не сможет его использовать.
Другими словами, это то же самое:
window.Issue = Issue;
Что я на самом деле предпочитаю большую часть времени.Более понятно, что происходит window
всегда означает window
, но @
может означать много вещей в зависимости от того, где оно появляется.
Другие советы
Как и в JavaScript, нет правильного пространства имен в CoffeeScript.@Issue = Issue
переводит на this.Issue = Issue
.Я предполагаю, что этот фрагмент предназначен для того, чтобы быть объединены с другими файлами во время сборки, один из них открывает анонимное закрытие, аналогично тем ниже.
var namespace1 = {subnamespace1: {}};
(function() {
// Several concatenated files
}).call(namespace1.subnamespace1);
.