Ich bemerke, dass ich ein wenig spät zu dieser Party komme, aber ich wollte eine Lösung einbringen, die ich in letzter Zeit benutzt habe. Aber zuerst möchte ich erwähnen...
Der Rails 3.1/3.2 Weg (Nein, Sir. Das gefällt mir nicht.)
Siehe: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Ich füge das Folgende der Vollständigkeit halber in diese Antwort ein, und weil es keine unhaltbare Lösung ist... obwohl es mir nicht besonders gefällt.
Der "Rails Weg" ist eine lösungsorientierte Lösung, anstelle einer ansichtsorientierten Lösung, wie vom ursprünglichen Autor dieser Frage gefordert. Es gibt controller-spezifische JS-Dateien, die nach ihren jeweiligen Controllern benannt sind. Alle diese Dateien werden in einem Ordnerbaum platziert, der standardmäßig in keinem der application.js-require-Direktiven enthalten ist.
Um kontrollerspezifischen Code einzuschließen, wird Folgendes zu einer Ansicht hinzugefügt.
<%= javascript_include_tag params[:controller] %>
Ich verabscheue diese Lösung, aber sie ist da und sie ist schnell. Möglicherweise könnten Sie stattdessen diese Dateien beispielsweise "people-index.js" und "people-show.js" nennen und dann etwas wie "#{params[:controller]}-index"
verwenden, um eine ansichtsorientierte Lösung zu erhalten. Wieder ein schneller Fix, aber ich fühle mich nicht wohl dabei.
Mein Datenattribut-Weg
Nennt mich verrückt, aber ich möchte ALLEN meinen JS kompiliert und minimiert in application.js haben, wenn ich deploye. Ich möchte nicht daran denken müssen, diese kleinen Straggler-Dateien überall einzufügen.
Ich lade all meinen JS in einer kompakten, bald im Browser zwischengespeicherten, Datei. Wenn ein bestimmter Teil meines application.js auf einer Seite ausgeführt werden muss, lasse ich mir von HTML sagen, nicht von Rails.
Anstatt meinen JS an spezifische Element-IDs zu binden oder meinen HTML mit Marker-Klassen zu übersäen, verwende ich ein benutzerdefiniertes Datenattribut namens data-jstags
.
Auf jeder Seite verwende ich - bevorzugte JS-Bibliotheksmethode hier einfügen -, um Code auszuführen, wenn das DOM fertig geladen ist. Dieser Bootstrap-Code führt die folgenden Aktionen aus:
- Iteriere über alle Elemente im DOM, die mit
data-jstag
markiert sind
- Für jedes Element, teile den Attributwert nach Leerzeichen auf und erstelle ein Array von Tag-Zeichenfolgen.
- Für jede Tag-Zeichenfolge suche in einem Hash nach diesem Tag.
- Wenn ein übereinstimmender Schlüssel gefunden wird, führe die zugehörige Funktion aus, wobei das Element als Parameter übergeben wird.
Angenommen, ich habe folgendes irgendwo in meinem application.js definiert:
function my_autosuggest_init(element) {
/* Füge Events hinzu, um die Eingabe zu überwachen und Vorschläge zu machen... */
}
function my_hint_init(element) {
/* Füge Events hinzu, um einen Hinweis bei Änderung/Blur anzuzeigen, wenn leer... */
/* Ja, ich weiß, dass HTML 5 dies nativ mit Attributen machen kann. */
}
var JSTags = {
'auto-suggest': my_autosuggest_init,
'hint': my_hint_init
};
Das Bootstrap-Ereignis wendet die Funktionen my_autosuggest_init
und my_hint_init
auf die Sucheingabe an, wodurch diese zu einer Eingabe wird, die eine Liste von Vorschlägen anzeigt, während der Benutzer tippt, sowie einen Eingabehinweis anzeigt, wenn die Eingabe leer und nicht fokussiert ist.
Sofern kein Element mit data-jstag="auto-suggest"
markiert ist, wird der Auto-Suggest-Code nie ausgeführt. Aber er ist immer da, minimiert und schließlich zwischengespeichert in meinem application.js für die Zeiten, in denen ich ihn auf einer Seite benötige.
Wenn Sie zusätzliche Parameter an Ihre markierten JS-Funktionen übergeben müssen, müssen Sie etwas kreativ sein. Fügen Sie entweder Data-Parameterattribute hinzu, überlegen Sie sich eine Art Parameter-Syntax oder verwenden Sie sogar einen hybriden Ansatz.
Auch wenn ich einen komplizierten Ablauf habe, der ansichtsspezifisch erscheint, erstelle ich einfach eine Datei dafür in meinem lib-Ordner, packe sie in application.js und markiere sie mit so etwas wie 'neue-sache-wizard'. Wenn mein Bootstrap dieses Tag erreicht, wird mein schöner, ausgefallener Wizard instanziiert und ausgeführt. Er läuft für die Ansichten dieses Controllers, wenn nötig, ist aber ansonsten nicht an den Controller gebunden. Tatsächlich, wenn ich meinen Wizard richtig programmiere, könnte ich alle Konfigurationsdaten in den Ansichten bereitstellen und meinen Wizard später für jeden anderen Controller wiederverwenden, der ihn benötigt.
Wie auch immer, das ist meine Art, seitenbezogenen JS bereits seit geraumer Zeit zu implementieren, und sie hat mir sowohl für einfache Seitendesigns als auch für komplexere/reichhaltige Anwendungen gut gedient. Hoffentlich ist eine der beiden Lösungen, die ich hier vorgestellt habe, meine Art oder der Rails-Weg, hilfreich für jeden, der diese Frage in Zukunft stößt.
11 Stimmen
"Der Weg von Rails 3.1 ist es, alle deine JavaScript-Dateien in eine Datei zu packen, anstatt einzelne JavaScript-Dateien am Ende jeder Seite zu laden." — Nur weil das Rails-Kernteam wirklich schlecht darin ist, zu wissen, wie man JavaScript verwaltet. Kleine Dateien sind im Allgemeinen besser (siehe meine Kommentare anderswo). Wenn es um JavaScript geht, ist der Rails-Weg selten der richtige Weg (außer beim Asset-Pipeline, die wirklich gut ist, und der Förderung von CoffeeScript).
0 Stimmen
So werden Sie Ihre seitenbezogenen JS-Dateien auf jeder Seite einfügen? Ich denke, das ist eine Verschwendung, ich stimme ClosureCowboys Antwort mehr zu.
1 Stimmen
Hast du dir die akzeptierte Antwort auf diese Frage angesehen? stackoverflow.com/questions/6571753/…
0 Stimmen
Psh, ich denke, ich werde bei Require.js bleiben :) Es gibt einen Compiler für RequireJS, der die Dateien bündelt, auf die Ihr Modul verweist.
0 Stimmen
@beefjerky "Wirst du also deine seiten-spezifischen JS-Dateien auf jeder Seite einbinden?" Auf keinen Fall. Auf jeder Seite inkludiere ich nur die JS-Dateien, die ich tatsächlich für diese Seite benötige. Wenn sie ordnungsgemäß modularisiert sind, werden sie vom Browser schnell zwischengespeichert.
0 Stimmen
@Ziggy Es mag konsistent sein, aber es ist nicht gut. :)
0 Stimmen
Für diejenigen, die ein vollständiges Verständnis dafür haben möchten, wie dies funktioniert und was am besten ist, lesen Sie bitte railsapps.github.io/rails-javascript-include-external.html . Dies ist meiner Meinung nach die beste Dokumentation, die ich zu diesem Thema gesehen habe. Es ist nicht nur ein großartiges Nachschlagewerk für Rails, sondern auch für alle, die sich mit Webentwicklung beschäftigen. Deshalb ist es am besten, Dinge auf die Art von Rails zu tun. Ich werde sicherlich Unholy Rails für meine zukünftigen Fragen verwenden. - Hinweis: Dies ist mein Kommentar zu einer ähnlichen Frage für diejenigen, die sie schon einmal gesehen haben. - @MarnenLaibow-Koser Ich denke, dir wird diese Lektüre wirklich gefallen.
0 Stimmen
@DutGRIFF Obwohl dies eine der besseren Diskussionen ist, die ich zu einem oft missverstandenen Thema gesehen habe, ermutigt es genau die Art von großen Küchenspülk JS-Dateien, die ich vermeiden würde. Lesen Sie es aufgrund seiner Diskussion über die Pipeline, aber ignorieren Sie seine Empfehlungen.
1 Stimmen
@DutGRIFF Mit anderen Worten: Nein, es ist in diesem Fall nicht am besten, die Dinge auf die Rails-Art zu tun (oder zumindest nicht alles in
application.js
zu platzieren), und tatsächlich zeigt die von Ihnen bereitgestellte Referenz auf, warum das so ist: Das Herunterladen ist der langsamste Teil des JS-Ausführungsprozesses. Viele kleine Dateien sind besser im Cache speicherbar als eine große. Die Unheiligen Rails-Leute scheinen dann nicht zu erkennen, dass ihre Empfehlungen mit den Grundsätzen, an die sie sich halten wollen, unvereinbar sind, und ihre Empfehlungen sollten daher nicht ernst genommen werden.0 Stimmen
Ich stimme mit vielem von dem überein, was du sagst. Ich kann definitiv sehen, wo eine große Website mit vielen seiten-spezifischen Skripts Probleme mit der kitchen-sink JS-Datei haben könnte, aber sobald sie gecacht ist, könnte es für den Rest dieser Website eine gute Sache sein. Ich würde es hassen, eine extrem große JS-Datei auf meinem Mobilgerät (langsames Internet) zu laden, nur um einem Link zu einer anderen Website zu folgen. Zum Beispiel beim Bezahlen meiner Harley-Rechnung. Gute Informationen. Danke.
1 Stimmen
@DutGRIFF Nein, eine große JS-Datei wäre normalerweise auch nach dem Zwischenspeichern keine gute Sache. Siehe meine Kommentare an anderer Stelle auf dieser Seite: Kleinere Dateien können bestimmte Seiten besser ansprechen und feiner zwischengespeichert werden. Ich sehe keinen guten Anwendungsfall für eine einzelne große Datei, es sei denn, es gibt überhaupt keinen seitenbezogenen Code weder.
0 Stimmen
Ebenso für Rails 3: stackoverflow.com/questions/3437585/…
0 Stimmen
Wenn Sie die Asset-Pipeline und die CoffeeScript-Implementierung verwenden, können Sie hier JS in CoffeeScript umwandeln. js2coffee.org