Verwenden einer Rails-Hilfsmethode in einem Javascript-Asset

70

Gibt es eine Möglichkeit, eine Rails-Hilfsmethode zu verwenden, insbesondere eine Pfadhilfemethode in einer Javascript-Asset-Datei? Diese Dateifoo.js.coffee.erb

$('#bar').val("<%= create_post_path %>")

Ich würde es lieben, wenn ich von Erubis bekommen könnte

$('#bar').val("path/to/create")
Axsuul
quelle
Hast du versucht das zu tun? Es sollte funktionieren.
Natedavisolds
1
Ja, ich habe es versucht, es gibt "undefinierte lokale Variable oder Methode". Ich habe andere Methoden ausprobiert wie ... number_to_currency
axsuul
Ich möchte darauf hinweisen, dass diese Hilfsmethode jedoch funktioniert: javscript_path ('path / to / js')
axsuul

Antworten:

76

Sie können jeden Helfer / jedes Modul / jede Klasse in eine erb-Vorlage aufnehmen mit:

<% environment.context_class.instance_eval { include MyHelper } %>

Siehe: https://github.com/rails/sprockets/blob/master/lib/sprockets/environment.rb und https://github.com/rails/sprockets/blob/master/lib/sprockets/context.rb

Um die URL-Helfer verwenden zu können, müssen Sie die Helfer Ihrer spezifischen Anwendungen einschließen.

Sie sind erhältlich bei Rails.application.routes.url_helpers:

<% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %>

BEARBEITEN: Links zu Repo mit bewegten Kettenrädern behoben, aber nicht wirklich sicher, ob dies noch so viele Jahre später Sinn macht.

eirc
quelle
Aber wie würden Sie das UrlHelpers-Modul einbinden? Und das Schlimme daran ist, dass die URL-Helfer zur Laufzeit ein Modell benötigen, Buy-Buy-Cowboy
Nikos D
14
Um die URL-Helfer verwenden zu können, müssen Sie die Helfer Ihrer spezifischen Anwendungen einschließen. Sie sind verfügbar bei Rails.application.routes.url_helpers: <% environment.context_class.instance_eval { include Rails.application.routes.url_helpers } %>
eirc
3
Fantastische Antwort! Wie haben Sie das herausgefunden? ist das bei den Rails Guides vorhanden? Ich dachte, ich hätte vielleicht etwas Ähnliches in einem RailsCast gesehen, diese Magie ist so mächtig, du musst es mir sagen, Mann!
jlstr
1
Ich bin mir nicht sicher, wie ich darauf gekommen bin, aber entweder durch Navigieren durch den Rails-Code (IntelliJ the IDE ( jetbrains.com/idea ) macht dies möglich und sehr einfach) oder durch Ausführen im Debug-Modus (loben Sie die IDE erneut :)
eirc
github links return 404 :(
pedrorijo91
27

Dies wird auch den Trick in einem Initialisierer tun:

Sprockets::Context.send :include, MyHelper

Im Entwicklungsmodus wird der Helfer nicht bei jeder Anforderung neu geladen.

Ihr Ansatz mit UrlHelpers funktioniert so lange, bis Sie ihn finden müssen post_path(...um...we don't know what post id we'll need at compile time...). Es gibt ein Rubinjuwel, das alle Ihre Rails UrlHelper in JavaScript neu implementiert: https://github.com/railsware/js-routes

user1158559
quelle
1
Ich musste meiner application.rb-Datei eine Schiene hinzufügen, da ich config.assets.initialize_on_precompile = false verwendete. stackoverflow.com/questions/9235292/… zum Einrichten der Schiene.
HannesBenson
19

Ich bin mir nicht ganz sicher, warum du das machen willst.

  • Sie würden verhindern, dass die Javascript-Datei zwischengespeichert wird, da sie einen dynamischen Wert enthält

  • Sie würden eine Kopplung zwischen Ihrem Javascript / Coffeescript und den Schienen erhalten

Wenn möglich, würde ich Ihnen raten, Ihr Problem zu abstrahieren, indem Sie Ihren Zielpfad in der Ansicht angeben und den Wert aus dem DOM-Element abrufen, wenn das bestimmte Ereignis eintritt. Genau wie bei "Unauffälligen Skriptadaptern" für Rails. Beispiel: https://github.com/rails/jquery-ujs/blob/master/src/rails.js#L157-173

topek
quelle
20
Dies würde das Caching nicht verhindern. Die Assets werden bei der Bereitstellung kompiliert und ändern sich nie. Dieser Pfad ändert sich nicht (es sei denn, dies geschieht tatsächlich und die Assets werden neu kompiliert.) Dies ist besonders nützlich, wenn Sie beispielsweise einen Image-Pfad in Ihrem JS verwenden möchten, der von Ihremasset_path
Brad
4
Wie oben erwähnt, möchte ich dies nicht tun, da dadurch die Kopplung zwischen Ihrer App und Ihrem JavaScript eingeführt wird. Jeder Teil Ihrer App sollte einem anderen Zweck dienen. Sie möchten nicht, dass Ihre Ansicht Modelllogik enthält, und ich persönlich möchte nicht, dass Rails-Code in mein JavaScript gelangt. Dies ist natürlich eine Art persönliche Präferenz. JavaScript bietet viele Möglichkeiten, Informationen aus dem DOM abzurufen, ohne direkt in das DOM eingefügt zu werden. Sie möchten diese Werte nicht fest codieren. Warum sollte es besser sein, wenn ein Helfer dies für Sie erledigt?
Topek
An welcher Stelle im Code zeigte der Github-Link ursprünglich, als er zum ersten Mal veröffentlicht wurde? Links zum "Master" -Zweig machen es nach einiger Zeit schwierig, ihnen zu folgen.
Valscion
8

In der Tat stimme ich der Antwort von @eirc zu (unter Berücksichtigung der Dokumentation von Sprockets). Aber ich würde in Betracht ziehen, Hilfsmodule beim Booten des Rails einzuschließen. Wie per

# config/initializers/sprockets.rb
Rails.application.assets.context_class.instance_eval do
  include ActionView::Helpers
  include Rails.application.routes.url_helpers
  include MyModule
end

Dies liegt an: https://github.com/rails/sprockets-rails/blob/master/lib/sprockets/railtie.rb#L23

Andrea Amantini
quelle
5

Eigentlich nicht sicher, ob dies hilft, aber es gibt eine Möglichkeit, Ihre eigenen Helfer für die Verwendung während zu definieren rake precompile

Erstellen Sie einen neuen Initialisierer und fügen Sie diesen ein:

module Sprockets
  module Helpers
    module RailsHelper

      def my_helper_method
       ...
      end

    end
  end
end

Und dann können Sie:

<%= my_helper_method %>

in Ihrem .erbVermögen

Matthew
quelle