Setahu saya, semua JavaScript Anda digabung menjadi 1 file. Rails melakukan ini secara default ketika menambahkan //= require_tree .
ke bagian bawah application.js
file manifes Anda .
Ini terdengar seperti penyelamat nyata, tapi saya sedikit khawatir tentang kode JavaScript khusus halaman. Apakah kode ini dijalankan pada setiap halaman? Hal terakhir yang saya inginkan adalah semua objek saya akan dipakai untuk setiap halaman ketika mereka hanya diperlukan pada 1 halaman.
Juga, bukankah ada potensi untuk kode yang berbenturan juga?
Atau apakah Anda meletakkan script
tag kecil di bagian bawah halaman yang hanya memanggil metode yang mengeksekusi kode javascript untuk halaman?
Apakah Anda tidak lagi memerlukan require.js?
Terima kasih
EDIT : Saya menghargai semua jawaban ... dan saya tidak berpikir mereka benar-benar mengerti masalahnya. Beberapa dari mereka adalah tentang gaya dan tampaknya tidak berhubungan ... dan yang lain hanya menyebutkan javascript_include_tag
... yang saya tahu ada (jelas ...) tetapi akan terlihat bahwa Rails 3.1 cara maju adalah untuk membungkus semua JavaScript Anda menjadi 1 file daripada memuat individu JavaScript di bagian bawah setiap halaman.
Solusi terbaik yang dapat saya temukan adalah dengan membungkus fitur-fitur tertentu dalam div
tag dengan id
s atau class
es. Dalam kode JavaScript, Anda hanya memeriksa apakah id
atau class
ada di halaman, dan jika itu adalah, Anda menjalankan kode JavaScript yang terkait dengan itu. Dengan cara ini jika elemen dinamis tidak ada di halaman, kode JavaScript tidak berjalan - meskipun sudah termasuk dalam masifapplication.js
file dikemas oleh Sprockets.
Solusi saya di atas memiliki manfaat bahwa jika kotak pencarian disertakan pada 8 dari 100 halaman, itu hanya akan berjalan pada 8 halaman tersebut. Anda juga tidak perlu memasukkan kode yang sama pada 8 halaman di situs. Bahkan, Anda tidak perlu memasukkan tag skrip manual di situs Anda di mana pun lagi.
Saya pikir ini adalah jawaban aktual untuk pertanyaan saya.
application.js
), dan pada kenyataannya referensi yang Anda berikan menunjukkan mengapa demikian: mengunduh adalah bagian paling lambat dari proses eksekusi JS. Banyak file kecil lebih dapat di-cache daripada yang besar. Orang-orang Unholy Rails tampaknya tidak menyadari, kemudian, bahwa rekomendasi mereka tidak konsisten dengan prinsip-prinsip yang mereka coba patuhi, dan oleh karena itu rekomendasi mereka tidak boleh dianggap serius.Jawaban:
Dokumen Asset Pipeline menyarankan cara melakukan JS khusus pengontrol:
Tautan ke: asset_pipeline
sumber
page_specific_js = "#{params[:controller]}_#{params[:action]}"
lalu;javascript_include_tag page_specific_js if Rails.application.assets.find_asset page_specific_js
Untuk js khusus laman, Anda dapat menggunakan solusi Garber-Irish .
Jadi folder javascripts Rails Anda mungkin terlihat seperti ini untuk dua pengontrol - mobil dan pengguna:
Dan javascripts akan terlihat seperti ini:
dan markup_based_js_execution akan berisi kode untuk objek UTIL, dan pada eksekusi UTIL.init yang siap DOM.
Dan jangan lupa letakkan ini di file layout Anda:
Saya juga berpikir bahwa lebih baik menggunakan kelas daripada
data-*
atribut, untuk css spesifik halaman yang lebih baik. Seperti yang disebutkan Jason Garber: penyeleksi CSS khusus laman dapat menjadi sangat aneh (ketika Anda menggunakandata-*
atribut)Saya harap ini akan membantu Anda.
sumber
window.varForOneController='val'
pada fungsi init pengontrol ini. Gon permata juga dapat membantu di sini ( github.com/gazay/gon ). Mungkin ada solusi lain.//= require_tree .
dan menggunakan JavaScript khusus halaman. Jika Anda secara aktif berusaha untuk tidak melakukannya, maka Anda berjuang untuk praktik yang buruk.Saya melihat bahwa Anda telah menjawab pertanyaan Anda sendiri, tetapi inilah pilihan lain:
Pada dasarnya, Anda membuat asumsi itu
Dibutuhkan. Ini bukan. Jangan ragu untuk menghapusnya. Dalam aplikasi saya saat ini, yang pertama saya lakukan dengan 3.1.x jujur, saya telah membuat tiga file JS tingkat atas yang berbeda.
application.js
File saya hanya punyaDengan cara ini, saya dapat membuat subdirektori, dengan file JS tingkat atas mereka sendiri, yang hanya menyertakan apa yang saya butuhkan.
Kuncinya adalah:
require_tree
- Rails memungkinkan Anda mengubah asumsi yang dibuatnyaapplication.js
- file apa pun dalamassets/javascript
subdirektori dapat menyertakan arahan pra-prosesor//=
Harapan yang membantu dan menambahkan beberapa detail pada jawaban ClosureCowboy.
Sujal
sumber
//= require_tree .
dengan//= require_directory .
sehingga Anda dapat menyimpan semua file yang ada di mana mereka berada dan membuat direktori baru untuk file khusus halaman.Pilihan lain: untuk membuat file khusus halaman atau model, Anda dapat membuat direktori di dalam
assets/javascripts/
folder Anda .application.js
File manifes utama Anda dapat dikonfigurasikan untuk memuat file-file tersebut dariglobal/
. Halaman atau grup halaman tertentu dapat memiliki manifesnya sendiri yang memuat file dari direktori spesifik mereka sendiri. Sprockets akan secara otomatis menggabungkan file yang dimuatapplication.js
dengan file khusus halaman Anda, yang memungkinkan solusi ini bekerja.Teknik ini dapat digunakan untuk
style_sheets/
juga.sumber
Saya menghargai semua jawaban ... dan saya pikir mereka tidak benar-benar mengerti masalahnya. Beberapa dari mereka adalah tentang gaya dan tampaknya tidak berhubungan ... dan yang lain hanya menyebutkan
javascript_include_tag
... yang saya tahu ada (jelas ...) tetapi akan terlihat bahwa Rails 3.1 cara maju adalah untuk membungkus semua Javascript Anda ke dalam 1 file daripada memuat Javascript individual di bagian bawah setiap halaman.Solusi terbaik yang dapat saya temukan adalah dengan membungkus fitur-fitur tertentu dalam
div
tag denganid
s atauclass
es. Dalam kode javascript. Kemudian Anda hanya memeriksa apakahid
atauclass
ada di halaman, dan jika ya, Anda menjalankan kode javascript yang terkait dengannya. Dengan cara ini jika elemen dinamis tidak ada di halaman, kode javascript tidak berjalan - meskipun sudah termasuk dalamapplication.js
file besar yang dikemas oleh Sprockets.Solusi saya di atas memiliki manfaat bahwa jika kotak pencarian disertakan pada 8 dari 100 halaman, itu hanya akan berjalan pada 8 halaman tersebut. Anda juga tidak perlu memasukkan kode yang sama pada 8 halaman di situs. Bahkan, Anda tidak akan pernah harus memasukkan tag skrip manual di situs Anda di mana pun lagi - kecuali untuk mungkin memuat ulang data.
Saya pikir ini adalah jawaban aktual untuk pertanyaan saya.
sumber
<script>
tag manual itu . Ya, kelas dan id adalah bagian dari jawabannya, tetapi tidak masuk akal bagi pengguna untuk memuat JavaScript yang tidak dibutuhkan oleh halaman tersebut.Saya menyadari bahwa saya datang ke pesta ini agak terlambat, tetapi saya ingin memberikan solusi yang saya gunakan belakangan ini. Namun, izinkan saya pertama menyebutkan ...
The Rails 3.1 / 3.2 Way (Tidak, tuan. Saya tidak suka itu.)
Lihat: http://guides.rubyonrails.org/asset_pipeline.html#how-to-use-the-asset-pipeline
Saya menyertakan yang berikut demi kelengkapan dalam jawaban ini, dan karena itu bukan solusi yang tidak dapat diperbaiki ... meskipun saya tidak terlalu peduli untuk itu.
"Rails Way" adalah solusi yang berorientasi pada pengontrol, daripada berorientasi pada pandangan seperti yang diminta oleh penulis asli dari pertanyaan ini. Ada file JS khusus pengontrol yang dinamai menurut pengontrolnya masing-masing. Semua file ini ditempatkan di pohon folder yang TIDAK termasuk secara default di salah satu application.js memerlukan arahan.
Untuk memasukkan kode khusus pengontrol, berikut ini ditambahkan ke tampilan.
Saya benci solusi ini, tetapi ada di sana dan cepat. Agaknya, Anda bisa memanggil file-file ini sesuatu seperti "people-index.js" dan "people-show.js" dan kemudian menggunakan sesuatu seperti
"#{params[:controller]}-index"
untuk mendapatkan solusi berorientasi tampilan. Sekali lagi, perbaikan cepat, tetapi itu tidak cocok dengan saya.Cara Atribut Data Saya
Panggil saya gila, tapi saya ingin SEMUA JS saya dikompilasi dan diperkecil ke dalam application.js ketika saya menyebarkan. Saya tidak ingin harus ingat untuk memasukkan file-file kecil yang lalai ini di semua tempat.
Saya memuat semua JS saya dalam satu file cache yang kompak, yang akan segera di-cache. Jika bagian tertentu dari application.js saya perlu diaktifkan pada halaman, saya membiarkan HTML memberitahu saya, bukan Rails.
Daripada mengunci JS saya ke ID elemen tertentu atau mengotori HTML saya dengan kelas marker, saya menggunakan atribut data khusus yang disebut
data-jstags
.Pada setiap halaman, saya menggunakan - masukkan metode perpustakaan JS yang disukai di sini - untuk menjalankan kode ketika DOM selesai memuat. Kode bootstrap ini melakukan tindakan berikut:
data-jstag
Jadi katakan saya memiliki yang berikut didefinisikan di suatu tempat di application.js saya:
Acara bootstrap akan menerapkan
my_autosuggest_init
danmy_hint_init
berfungsi terhadap input pencarian, mengubahnya menjadi input yang menampilkan daftar saran saat pengguna mengetik, serta memberikan semacam petunjuk input ketika input dibiarkan kosong dan tidak fokus.Kecuali beberapa elemen ditandai
data-jstag="auto-suggest"
, kode saran otomatis tidak pernah diaktifkan. Namun, selalu ada di sana, diperkecil, dan akhirnya di-cache dalam aplikasi saya. Untuk saat itu saya membutuhkannya di halaman.Jika Anda perlu memberikan parameter tambahan ke fungsi JS yang ditandai, Anda harus menerapkan beberapa kreativitas. Entah menambahkan atribut data-paramter, menghasilkan beberapa jenis sintaks parameter, atau bahkan menggunakan pendekatan hybrid.
Bahkan jika saya memiliki beberapa alur kerja rumit yang tampaknya khusus untuk kontroler, saya hanya akan membuat file untuk itu di folder lib saya, masukkan ke application.js, dan beri tag dengan sesuatu seperti 'new-thing-wizard'. Ketika bootstrap saya mengenai tag itu, wizard saya yang bagus dan mewah akan dipakai dan dijalankan. Ini berjalan untuk tampilan pengontrol ketika diperlukan, tetapi tidak jika digabungkan ke controller. Bahkan, jika saya mengkodekan wizard saya dengan benar, saya mungkin dapat memberikan semua data konfigurasi dalam tampilan dan karena itu dapat menggunakan kembali wizard saya nanti untuk pengontrol lain yang membutuhkannya.
Bagaimanapun, ini adalah bagaimana saya telah mengimplementasikan JS halaman spesifik untuk sementara waktu sekarang, dan itu telah membantu saya dengan baik untuk desain situs sederhana dan untuk aplikasi yang lebih kompleks / kaya. Semoga salah satu dari dua solusi yang saya sajikan di sini, cara saya atau cara Rails, sangat membantu bagi siapa saja yang menemukan pertanyaan ini di masa depan.
sumber
Ini telah dijawab dan diterima sejak lama, tetapi saya menemukan solusi saya sendiri berdasarkan beberapa jawaban ini dan pengalaman saya dengan Rails 3+.
Pipa asetnya manis. Gunakan.
Pertama, di
application.js
file Anda , hapus//= require_tree.
Kemudian di Anda
application_controller.rb
buat metode pembantu:Kemudian di
application.html.erb
file tata letak Anda , tambahkan pembantu baru Anda di antara javascript yang ada, diawali denganraw
pembantu:Voila, sekarang Anda dapat dengan mudah membuat javascript khusus tampilan menggunakan struktur file yang sama yang Anda gunakan di tempat lain di rails. Cukup tempelkan file Anda
app/assets/:namespace/:controller/action.js.erb
!Semoga itu bisa membantu orang lain!
sumber
<%= raw ... %>
akan mengembalikan 404?require_tree /
(buruk)?Anda dapat menambahkan baris ini di file tata letak Anda (mis. Application.html.erb) untuk secara otomatis memuat file javascript khusus controller (yang dibuat saat Anda membuat controller):
Anda juga bisa menambahkan baris untuk memuat file skrip secara otomatis dalam basis per tindakan.
Cukup masukkan skrip halaman Anda ke dalam subdirektori yang dinamai menurut nama pengontrol. Dalam file-file ini Anda dapat menyertakan skrip lain menggunakan = wajib. Akan lebih baik untuk membuat helper untuk memasukkan file hanya jika ada, untuk menghindari kegagalan 404 di browser.
sumber
sumber
Mungkin Anda akan menemukan permata pluggable_js sebagai solusi yang sesuai.
sumber
The LoadJS permata adalah pilihan lain:
sumber
Jawaban Philip cukup bagus. Berikut adalah kode untuk membuatnya berfungsi:
Di application.html.erb:
<body class="<%=params[:controller].parameterize%>">
Dengan asumsi pengontrol Anda disebut Proyek, yang akan menghasilkan:
<body class="projects">
Kemudian di projects.js.coffee:
sumber
<body>
adalah ipso facto tidak benar. Lihat komentar saya di tempat lain di halaman ini.JavaScripts hanya digabung ketika Anda memberi tahu Rails (Sprockets, bukan) untuk menggabungkannya.
sumber
//= require_tree .
?require_tree .
biasanya ide yang buruk.Ini adalah bagaimana saya memecahkan masalah styling: (permisi Haml)
Dengan cara ini saya memulai semua file .css.sass halaman khusus dengan:
Dengan cara ini Anda dapat dengan mudah menghindari bentrokan. Ketika datang ke file .js.coffee Anda hanya bisa menginisialisasi elemen seperti;
Semoga ini bisa membantu.
sumber
$('#post > #edit') ->
tampaknya tidak valid. Bagaimana Anda lingkup jQuery untuk bekerja dalam lingkup?= javascript_include_tag "application"
dan= javascript_include_tag params[:controller]
dengan cara ini saya dapat menyimpan kode javascript tanpa harus menentukan lingkup di dalam file.Anda juga dapat mengelompokkan js dalam folder dan terus menggunakan pipa aset untuk memuat javascript Anda secara selektif tergantung pada halaman.
sumber
Saya setuju dengan jawaban Anda, untuk memeriksa apakah pemilih itu ada, gunakan:
(tidak melihat orang menambahkan solusi yang sebenarnya)
sumber
Saya tidak melihat jawaban yang benar-benar menyatukan dan menjabarkannya untuk Anda. Jadi, saya akan mencoba untuk menempatkan meleyal , Sujal (a la ClosureCowboy ), bagian pertama dari Ryan jawaban, dan bahkan Gal pernyataan berani tentang Backbone.js ... semua bersama-sama dengan cara yang singkat dan jelas. Dan, siapa tahu, saya bahkan mungkin bertemu Marnen Laibow-Koser .
Contoh suntingan
aset / javascripts / application.js
views / layouts / application.html.erb
views / foo / index.html.erb
aset / javascripts / foo.js
aset / javascripts / foostuff / foothis.js.coffee
Deskripsi singkat
Hapus
//= require_tree .
dari application.js dan daftarkan hanya JS yang dibagi setiap halaman.Dua baris yang ditunjukkan di atas di application.html.erb memberi tahu halaman tempat menyertakan application.js dan JS khusus laman Anda.
Tiga baris yang ditunjukkan di atas dalam index.html.erb memberitahu pandangan Anda untuk mencari beberapa JS khusus halaman dan memasukkannya pada wilayah hasil bernama bernama ": javascript" (atau apa pun yang Anda ingin beri nama). Dalam contoh ini, pengontrolnya adalah "foo" sehingga Rails akan berusaha memasukkan "foo.js" di: area javascript menghasilkan dalam tata letak aplikasi.
Buat daftar JS khusus halaman Anda di foo.js (atau apa pun nama pengontrolnya). Daftar perpustakaan umum, pohon, direktori, apa pun.
Simpan JS khusus halaman khusus Anda di tempat yang mudah Anda rujuk selain JS khusus Anda. Dalam contoh ini, foo.js memerlukan pohon foostuff jadi letakkan JS kustom Anda di sana, seperti foothis.js.coffee .
Tidak ada aturan keras di sini. Jangan ragu untuk memindahkan barang-barang dan bahkan mungkin membuat beberapa wilayah hasil dari berbagai nama dalam berbagai tata letak jika diperlukan. Ini hanya menunjukkan satu kemungkinan langkah maju pertama. (Saya tidak melakukannya persis seperti ini karena kami menggunakan Backbone.js. Saya mungkin juga memilih untuk menjatuhkan foo.js ke dalam folder bernama foo, bukan foostuff tetapi belum memutuskannya.)
Catatan
Anda dapat melakukan hal serupa dengan CSS dan
<%= stylesheet_link_tag params[:controller] %>
tetapi ini di luar cakupan pertanyaan.Jika saya melewatkan praktik terbaik yang mencolok di sini, kirimkan saya catatan dan saya akan menyesuaikan conisder. Rails cukup baru bagi saya dan, sejujurnya, sejauh ini saya tidak terkesan dengan kekacauan yang diakibatkan oleh pengembangan perusahaan dan semua lalu lintas yang dihasilkan oleh program Rails rata-rata.
sumber
Saya punya solusi lain, yang walaupun primitif berfungsi dengan baik untuk saya dan tidak memerlukan strategi pemuatan selektif yang mewah. Masukkan fungsi siap dokumen nornal Anda, tetapi kemudian menguji lokasi windows saat ini untuk melihat apakah itu halaman javascript Anda dimaksudkan untuk:
Ini masih memungkinkan semua js dimuat oleh rel 3.x dalam satu paket kecil, tetapi tidak menghasilkan banyak overhead atau konflik dengan halaman yang tidak dimaksudkan js.
sumber
jawaban ryguy adalah jawaban yang baik, meskipun sudah diturunkan ke poin negatif.
Terutama jika Anda menggunakan sesuatu seperti Backbone JS - setiap halaman memiliki tampilan Backbone sendiri. Kemudian file erb hanya memiliki satu baris javascript inline yang menjalankan kelas tampilan backbone kanan. Saya menganggapnya sebagai satu baris 'kode lem' dan oleh karena itu fakta bahwa inline-nya OK. Keuntungannya adalah Anda dapat menyimpan "require_tree" yang memungkinkan cache browser semua javascript.
di show.html.erb, Anda akan memiliki sesuatu seperti:
dan di file tata letak Anda, Anda perlu:
sumber
Pindahkan semua file JS commom Anda ke sub-folder seperti 'app / assets / javascript / global' lalu di application.js, ubah
//= require_tree .
baris menjadi//= require_tree ./global
.Sekarang Anda bebas menempatkan JS khusus-pengontrol Anda di root 'app / aset / javascript /' dan mereka tidak akan dimasukkan dalam JS yang dikompilasi, yang digunakan hanya ketika Anda memanggilnya melalui
= javascript_include_tag
pada pengontrol / tampilan Anda.sumber
Meskipun Anda memiliki beberapa jawaban di sini, saya pikir hasil edit Anda mungkin yang terbaik. Pola desain yang kami gunakan di tim kami yang kami dapatkan dari Gitlab adalah pola Dispatcher. Itu melakukan sesuatu yang mirip dengan apa yang Anda bicarakan, namun nama halaman diatur dalam tag tubuh dengan rel. Misalnya, dalam file tata letak Anda, cukup sertakan sesuatu seperti (dalam HAML):
Maka hanya ada satu penutupan dan pernyataan beralih di
dispatcher.js.coffee
file Anda di folder javascripts Anda seperti:Yang perlu Anda lakukan dalam file individual (katakan
products.js.coffee
ataulogin.js.coffee
misalnya) adalah melampirkannya di kelas dan kemudian mengglobal simbol kelas itu sehingga Anda dapat mengaksesnya di dispatcher:Gitlab memiliki beberapa contoh tentang hal ini yang mungkin ingin Anda perhatikan jika Anda penasaran :)
sumber
Proyek Paloma menawarkan pendekatan menarik untuk mengelola kode javascript khusus halaman.
Contoh penggunaan dari dokumen mereka:
sumber
Langkah 1. hapus require_tree. di application.js dan application.css Anda.
Langkah 2. Edit application.html.erb Anda (berdasarkan rails default) di folder layout. Tambahkan "params [: controller]" di tag berikut.
Step3. Tambahkan file di config / initializers / assets.rb
referensi: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/
sumber
Saya belum mencoba ini, tetapi sepertinya yang berikut ini benar:
jika Anda memiliki content_for yaitu javascript (mis. dengan javascript nyata di dalamnya), sprocket tidak akan mengetahuinya dan karenanya ini akan bekerja dengan cara yang sama seperti sekarang.
jika Anda ingin mengecualikan file dari bundel besar javascript, Anda akan masuk ke file config / sprockets.yml dan memodifikasi source_files sesuai. Kemudian, Anda hanya perlu memasukkan file yang Anda kecualikan jika diperlukan.
sumber
Saya melakukannya sebelumnya menggunakan metode ini: http://theflyingdeveloper.com/controller-specific-assets-with-rails-4/ . Sangat mudah, bergantung pada pengontrol untuk memilih js yang tepat untuk dimuat.
sumber
Saya menggabungkan beberapa jawaban menjadi:
Penolong aplikasi:
tata letak / application.html.haml:
sumber
Pertama: hapus
\\=require_tree
dari application.js Kedua: semua kode JS Anda harus dialokasikan di/app/assets/javascritpt
dan semua kode CSS Anda harus dialokasikan di/app/assets/stylesheets
sumber
Mengikuti petunjuk dari Ryan, inilah yang telah saya lakukan-
application.js.coffee
users.js.coffee (skrip kopi kontroler khusus, mis. kontroler: pengguna, aksi: dasbor)
application.html.haml
sumber
eval
) jika HTML Anda dikompromikan oleh server yang retak atau skrip pengguna yang berbahaya.Inilah cara melakukannya terutama jika Anda tidak harus mengeksekusi banyak pustaka untuk halaman spesifik Anda, tetapi hanya untuk menjalankan beberapa ratus baris JS lebih atau kurang.
Karena sangat baik untuk menanamkan kode Javascript ke dalam HTML, buat saja di bawah direktori app / views shared.js dan letakkan di sana halaman / kode spesifik halaman Anda di dalam my_cool_partial.html.erb
Jadi sekarang dari mana pun Anda mau, Anda cukup melakukannya:
Dan itu saja, k?
sumber