389 Stimmen

Unter Verwendung von Rails 3.1, wo platzieren Sie Ihren "seitenübergreifenden" JavaScript-Code?

Nach meinem Verständnis wird Ihr gesamter JavaScript-Code in eine Datei zusammengeführt. Rails macht dies standardmäßig, wenn es //= require_tree . am Ende Ihrer application.js-Manifestdatei hinzufügt.

Dies klingt wie ein Lebensretter, aber ich mache mir ein wenig Sorgen um seitenbezogenen JavaScript-Code. Wird dieser Code auf jeder Seite ausgeführt? Das Letzte, was ich möchte, ist, dass alle meine Objekte für jede Seite instanziiert werden, wenn sie nur auf einer Seite benötigt werden.

Besteht nicht auch das Risiko von konkurrierendem Code?

Oder setzen Sie einfach ein kleines script-Tag am Ende der Seite, das einfach eine Methode aufruft, die den JavaScript-Code für die Seite ausführt?

Brauchen Sie dann nicht mehr require.js?

Danke

EDIT: Ich schätze alle Antworten... aber ich glaube nicht, dass sie wirklich das Problem ansprechen. Einige von ihnen handeln von Styling und scheinen nicht zuzutreffen... und andere erwähnen nur javascript_include_tag... was ich weiß (offensichtlich...) aber anscheinend ist der Weg für Rails 3.1, zukünftig Ihren gesamten JavaScript-Code in eine Datei zu packen, anstatt einzelnes JavaScript am Ende jeder Seite zu laden.

Die beste Lösung, die ich mir vorstellen kann, ist, bestimmte Funktionen in div-Tags mit ids oder classen zu packen. Im JavaScript-Code prüfen Sie einfach, ob die id oder class auf der Seite vorhanden ist, und wenn ja, führen Sie den entsprechenden JavaScript-Code aus. Auf diese Weise wird der JavaScript-Code nicht ausgeführt, wenn das dynamische Element nicht auf der Seite ist - obwohl er in der großen application.js-Datei enthalten ist, die von Sprockets gebündelt wird.

Meine obige Lösung hat den Vorteil, dass z.B. wenn eine Suchleiste auf 8 der 100 Seiten enthalten ist, sie nur auf diesen 8 Seiten läuft. Außerdem müssen Sie den Code nicht auf 8 der Seiten der Website einfügen. Tatsächlich müssen Sie niemals wieder manuelle Skript-Tags auf Ihrer Website einfügen.

Ich denke, das ist die eigentliche Antwort auf meine Frage.

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/…

5voto

meleyal Punkte 30244

Der LoadJS Edelstein ist eine weitere Option:

LoadJS bietet eine Möglichkeit, seitenbezogenen Javascript-Code in einer Rails-App zu laden, ohne die Magie von Sprockets zu verlieren. Der gesamte Javascript-Code wird weiterhin in einer Datei minifiziert, aber einige Teile davon werden nur für bestimmte Seiten ausgeführt.

https://github.com/guidomb/loadjs

3voto

Rahil Sondhi Punkte 646

Die Antwort von Philip ist ziemlich gut. Hier ist der Code, um es zum Laufen zu bringen:

In application.html.erb:

Angenommen, Ihr Controller heißt Projekte, das wird generiert:

Dann in projects.js.coffee:

jQuery ->
  if $('body.projects').length > 0  
     $('h1').click ->
       alert 'you clicked on an h1 in Projects'

0 Stimmen

Downvoting: Jede Lösung, die eine Klasse auf den setzt, ist ipso facto falsch. Siehe meine Kommentare an anderer Stelle auf dieser Seite.

0 Stimmen

Nicht tun. Das Problem hier ist, dass jedes Mal, wenn Sie eins davon hinzufügen, ein weiteres Stück js hinzugefügt wird, das beim Laden der Seite ausgeführt werden muss. Dies könnte definitiv zu Leistungsabfall führen, wenn Ihr Projekt wächst.

2voto

juanitogan Punkte 1508

Ich sehe keine Antwort, die wirklich alles zusammenfasst und für dich darstellt. Deshalb werde ich versuchen, meleyal, sujal (à la ClosureCowboy), den ersten Teil von Ryans Antwort und sogar Gals kühne Aussage über Backbone.js... alles zusammen auf eine kurze und klare Weise zu bringen. Und wer weiß, vielleicht erfülle ich sogar die Anforderungen von Marnen Laibow-Koser.

Beispielbearbeitungen

assets/javascripts/application.js

//= require jquery
//= require jquery_ujs
//= require lodash.underscore.min
...

views/layouts/application.html.erb

  ...

  <%= javascript_include_tag "application" %>
  <%= yield :javascript %>

views/foo/index.html.erb

...
<% content_for :javascript do %>
  <%= javascript_include_tag params[:controller] %>
<% end %>

assets/javascripts/foo.js

//= require moment
//= require_tree ./foostuff

assets/javascripts/foostuff/foothis.js.coffee

alert "Hallo Welt!"

Kurze Beschreibung

  • Entfernen Sie //= require_tree . aus application.js und listen Sie nur die JS auf, die jede Seite gemeinsam hat.

  • Die beiden oben gezeigten Zeilen in application.html.erb sagen der Seite, wo sie application.js und Ihr seitenbezogenes JS einbinden soll.

  • Die drei oben gezeigten Zeilen in index.html.erb sagen Ihrer Ansicht, dass sie nach einem seitenbezogenen JS suchen und es an einer benannten Yield-Region namens ":javascript" (oder wie auch immer Sie sie nennen möchten) einbinden soll. In diesem Beispiel ist der Controller "foo", also wird Rails versuchen, "foo.js" an der :javascript-Yield-Region im Anwendungslayout einzubinden.

  • Liste dein seitenbezogenes JS in foo.js (oder wie auch immer der Controller heißt). Liste gemeinsame Bibliotheken, ein Verzeichnis, Verzeichnisse, was auch immer.

  • Platzieren Sie Ihr benutzerdefiniertes seitenbezogenes JS an einer Stelle, an der Sie leicht darauf verweisen können, abgesehen von Ihrem anderen benutzerdefinierten JS. In diesem Beispiel erfordert foo.js den foostuff-Baum, also platzieren Sie Ihr benutzerdefiniertes JS dort, wie z.B. in foothis.js.coffee.

  • Hier gibt es keine harten Regeln. Fühlen Sie sich frei, Dinge zu verschieben und vielleicht sogar mehrere Yield-Regionen verschiedener Namen in verschiedenen Layouts zu erstellen, wenn nötig. Dies zeigt nur einen möglichen ersten Schritt nach vorne. (Ich mache es nicht genau so wie hier, angesichts unserer Verwendung von Backbone.js. Ich könnte auch entscheiden, foo.js in einen Ordner namens foo anstelle von foostuff zu verschieben, habe mich aber noch nicht entschieden.)

Anmerkungen

Sie können Ähnliches mit CSS und <%= stylesheet_link_tag params[:controller] %> tun, aber das ist über den Umfang der Frage hinaus.

Wenn ich hier eine offensichtliche Best Practice übersehen habe, schicken Sie mir eine Notiz und ich werde eine Anpassung in Betracht ziehen. Rails ist für mich ziemlich neu und ehrlich gesagt bin ich bisher nicht besonders beeindruckt von dem Chaos, das es standardmäßig für die Unternehmensentwicklung mit sich bringt und dem ganzen Traffic, den das durchschnittliche Rails-Programm erzeugt.

0 Stimmen

Dies scheint der richtige Weg zu sein, ich werde sehen, ob ich es in meiner eigenen App umsetzen kann, danke für die ausführliche Antwort.

2voto

Kyle C Punkte 4067

Ich stimme deiner Antwort zu, um zu überprüfen, ob dieser Selektor vorhanden ist, verwende:

if ($(selector).length) {
    // Fügen Sie die Funktion ein, die nicht auf jeder Seite ausgeführt werden muss
}

(Ich habe niemanden die tatsächliche Lösung hinzufügen sehen)

2voto

Kenny Grant Punkte 8822

Sie können auch den js in Ordnern gruppieren und weiterhin die Asset-Pipeline verwenden, um Ihre Javascript-Dateien selektiv zu laden abhängig von der Seite.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X