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

2voto

zeeraw Punkte 5157

Dies ist, wie ich das Style-Problem gelöst habe: (entschuldigen Sie das Haml)

%div{:id => "#{params[:controller].parameterize} #{params[:view]}"}
    = yield

So starte ich alle seitenbezogenen .css.sass Dateien mit:

#post
  /* Controller-spezifischer Code hier */
  &#index
    /* Ansicht-spezifischer Code hier */
  &#new
  &#edit
  &#show

So können Sie ganz einfach Kollisionen vermeiden. Wenn es um .js.coffee Dateien geht, könnten Sie Elemente einfach initialisieren wie;

$('#post > #edit') ->
  $('form > h1').css('float', 'right')

Ich hoffe, das hat geholfen.

1 Stimmen

Bitte lies den letzten Abschnitt noch einmal, für Javascript kannst du von der gleichen Struktur profitieren, die für Stylesheets zur Initialisierung von view-spezifischen Funktionen verwendet wird.

0 Stimmen

Philip, $('#post > #edit') -> scheint ungültig zu sein. Wie kann man jQuery umgrenzen, um innerhalb eines Bereichs zu arbeiten?

2 Stimmen

Kürzlich habe ich begonnen, alle Controller-spezifischen JavaScripts und Stylesheets zu laden, indem ich dies in der application.html.haml aufrufe; = javascript_include_tag "application" und = javascript_include_tag params[:controller] Auf diese Weise kann ich den JavaScript-Code begrenzen, ohne einen Bereich in der Datei angeben zu müssen.

2voto

yfeldblum Punkte 64211

JavaScripts werden nur zusammengeführt, wenn Sie Rails (genauer gesagt Sprockets) dazu auffordern, sie zusammenzuführen.

0 Stimmen

Natürlich. Ich nehme an, ich frage, weil die Standards von Rails alles im Ordner einschließen ... was bedeutet, dass David will, dass du das tust. Aber wie ich bereits im anderen Kommentar an @rubyprince gesagt habe, bin ich mir unsicher über die Ausführung, wenn es auf diese Weise gemacht wird. Ich denke, dass ich //= require_tree . deaktivieren muss?

0 Stimmen

@FireEmblem Ja. require_tree . ist in der Regel eine schlechte Idee.

1voto

zavg Punkte 9345

Das Paloma-Projekt bietet einen interessanten Ansatz zur Verwaltung von seitenabhängigem JavaScript-Code.

Ein Anwendungsbeispiel aus ihrer Dokumentation:

var UsersController = Paloma.controller('Benutzer');

// Wird ausgeführt, wenn Rails User#new aufgerufen wird.
UsersController.prototype.new = function(){
   alert('Hallo Sexy Benutzer!');
};

1voto

onetwopunch Punkte 3199

Auch wenn Sie hier mehrere Antworten haben, denke ich, dass Ihre Bearbeitung wahrscheinlich die beste Wahl ist. Ein Designmuster, das wir in unserem Team verwenden und das wir von Gitlab übernommen haben, ist das Dispatcher-Muster. Es führt etwas Ähnliches wie das aus, worüber Sie sprechen, jedoch wird der Seitenname im body-Tag von Rails festgelegt. Zum Beispiel, in Ihrer Layout-Datei, fügen Sie einfach etwas wie (in HAML) ein:

%body{'data-page' => "#{controller}:#{action}" }

Dann haben Sie nur einen Abschluss und eine switch-Anweisung in Ihrer dispatcher.js.coffee-Datei in Ihrem javascripts-Ordner, wie hier gezeigt:

$ ->
  new Dispatcher()

class Dispatcher
  constructor: ->
    page = $('body').attr('data-page')
    switch page
      when 'products:index'
        new Products() 
      when 'users:login'
        new Login()

Alles, was Sie in den einzelnen Dateien (zum Beispiel products.js.coffee oder login.js.coffee) tun müssen, ist, sie in eine Klasse einzuschließen und dann dieses Klassensymbol global zu machen, damit Sie darauf im Dispatcher zugreifen können:

class Products
  constructor: ->
    # do stuff
@Products = Products

Gitlab hat mehrere Beispiele dafür, mit denen Sie herumspielen können, falls Sie neugierig sind :)

1voto

Gedean Dias Punkte 1013

Verschieben Sie alle Ihre gemeinsamen JS-Dateien in einen Unterordner wie 'app/assets/javascript/global' und ändern Sie dann in der application.js die Zeile //= require_tree . in //= require_tree ./global.

Jetzt sind Sie frei, Ihren Controller-spezifischen JS im Stammverzeichnis 'app/assets/javascript/' zu platzieren und sie werden nicht im kompilierten JS enthalten, sondern nur verwendet, wenn Sie sie über = javascript_include_tag in Ihrem Controller/View aufrufen.

0 Stimmen

Keine Chance, das ist eine Menge JavaScript, das für eine Seite geladen werden muss. Es spielt nicht einmal eine Rolle, ob es zwischengespeichert ist.

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