Wie funktioniert Namespacing in Coffeescript und Rails?
-
24-12-2019 - |
Frage
Ich schaue mir dieses Kaffeeskript an Codes von Gitlab und frage mich, wie es funktioniert.
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
Es scheint, dass dies nur in den problembezogenen Ansichten verwendet wird, aber nirgendwo im HTML-Code der Probleme aufgerufen wird.Geht hier etwas Magisches hinter den Kulissen vor sich?Auch was ist die Bedeutung der @Issue = Issue
leitung?
Lösung
@Issue = Issue
veröffentlicht einfach eine lokale Variable im globalen Bereich.Das hat nichts mit Ruby oder Rails zu tun.Es ist eine reine Kaffeeskriptsprache.
CoffeeScript wird in einem Wrapper ausgeführt, der das Erstellen von Variablen im globalen Bereich verhindern soll.Und in diesem Wrapper, this
(oder @
) ist das globale Objekt.
Also das:
class Issue
constructor: ->
@Issue = Issue;
Kompiliert ungefähr zu diesem JS:
(function() {
var Issue;
Issue = (function() {
function Issue() {}
return Issue;
})();
this.Issue = Issue;
}.call(window));
In diesem JS, window
werden this
, und Eigenschaften des Fensters werden globale Variablen.Von nun an müssen Sie also nur noch tippen Issue
in jeder anderen JS-Datei haben Sie den Ausgabekonstruktor.
Ohne die @Issue = Issue
linie, die Issue
konstruktor wäre niemals außerhalb dieses Codes verfügbar, und keine andere Datei könnte ihn verwenden.
Mit anderen Worten, es ist das gleiche wie das:
window.Issue = Issue;
Was ich eigentlich die meiste Zeit bevorzuge.Es ist klarer, was als los ist window
bedeutet immer window
, aber @
kann viele Dinge bedeuten, je nachdem, wo es erscheint.
Andere Tipps
Genau wie in JavaScript gibt es in Coffeescript keinen richtigen Namespace. @Issue = Issue
übersetzt in this.Issue = Issue
.Ich vermute, dass dieses Snippet während des Erstellens mit anderen Dateien verkettet werden soll, von denen eine einen anonymen Abschluss öffnet, ähnlich dem folgenden.
var namespace1 = {subnamespace1: {}};
(function() {
// Several concatenated files
}).call(namespace1.subnamespace1);