Layout rel per aksi?

165

Saya menggunakan tata letak yang berbeda untuk beberapa tindakan (kebanyakan untuk tindakan baru di sebagian besar pengontrol).

Saya bertanya-tanya apa cara terbaik untuk menentukan tata letak? (Saya menggunakan 3 atau lebih layout yang berbeda di controller yang sama)

Saya tidak suka menggunakan

render: layout => 'name'

Saya suka melakukannya

tata letak 'nama',: hanya => [: baru]

Tapi saya tidak bisa menggunakannya untuk menentukan 2 atau lebih layout yang berbeda.

Sebagai contoh:

Ketika saya memanggil tata letak 2 kali dalam pengontrol yang sama, dengan nama tata letak yang berbeda dan hanya opsi yang berbeda, yang pertama diabaikan - tindakan tersebut tidak ditampilkan dalam tata letak yang saya tentukan.

Catatan: Saya menggunakan Rails 2.

mrbrdo
sumber
1
Dokumentasi The Rails Guides: guides.rubyonrails.org/...
Kevin
1
Poin yang bagus. Dokumentasi untuk Rails 2: guides.rubyonrails.org/v2.3.11/…
Kevin
2
(Juga, saya memposting panduan untuk membantu pembaca masa depan. Saya tidak ragu Anda telah memecahkan masalah Anda sejak lama ;-)
Kevin

Jawaban:

297

Anda dapat menggunakan metode untuk mengatur tata letak.

class MyController < ApplicationController
  layout :resolve_layout

  # ...

  private

  def resolve_layout
    case action_name
    when "new", "create"
      "some_layout"
    when "index"
      "other_layout"
    else
      "application"
    end
  end
end
Lilleaas Agustus
sumber
22
Keren Terimakasih. Dan jika seseorang ingin melakukan hal-hal yang lebih sederhana dengan one-liner, yang berikut ini mungkin dilakukan. Mudah dibaca dan ditempatkan di atas pengontrol. ---layout Proc.new{ ['index', 'new', 'create'].include?(action_name) ? 'some_layout' : 'other_layout' }
holli
1
Apakah ini akan berpengaruh besar pada kinerja aplikasi jika berbagai tata letak menggunakan katakanlah beberapa file css & js yang berbeda masing-masing?
Noz
15
-1: Terlalu rumit. Komentar di bawah ini ( stackoverflow.com/a/21203783/285154 ) adalah pilihan terbaik.
dimitarvp
Terima kasih! Ini masih menjadi masalah di Rails 4.2, mungkin hanya jika Anda menggunakan pengontrol bawaan di banyak level. Saya telah menggunakan metode sebelumnya, tetapi tidak berpikir untuk menguji ketika saya memiliki masalah sekarang, terima kasih lagi.
244an
@ demitko tidak bukan, saya sudah mereferensikan solusi itu dalam pertanyaan itu sendiri. Ini tidak berfungsi jika Anda ingin menggunakan 3 atau lebih tata letak yang berbeda (seperti halnya kasus saya).
mrbrdo
201

Jika Anda hanya memilih di antara dua tata letak, Anda dapat menggunakan :only:

class ProductsController < ApplicationController
   layout "admin", only: [:new, :edit]
end

atau

class ProductsController < ApplicationController
   layout "application", only: [:index]
end
axeltaglia
sumber
2
Nah, masalah dengan ini adalah bahwa Anda tidak dapat mengakses objek seperti current_user untuk menentukan tata letak
Andrew K
@AndrewK Memilih tata letak secara dinamis sepertinya bukan bagian dari pertanyaan yang diajukan.
Nick
11
Jika ada di antara Anda membaca pertanyaan Anda akan tahu ini bukan jawaban yang tepat, karena saya telah menggambarkan solusi ini dalam pertanyaan itu sendiri dan juga mengapa itu tidak berhasil dalam kasus saya (3 tata letak atau lebih).
mrbrdo
2
Seperti kata mrbrdo, ini bukan jawabannya. Pertanyaannya secara khusus menunjukkan (I am using 3 or more different layouts in the same controller). Jawaban ini memungkinkan tata letak dan tanpa tata letak, bukan tata letak yang berbeda.
Michael
49

Anda dapat menentukan tata letak untuk tindakan individual menggunakan respond_to :

  def foo
    @model = Bar.first
    respond_to do |format|
      format.html {render :layout => 'application'}
    end
  end
Gavin Terrill
sumber
Bagi saya ini adalah jawaban yang lebih fleksibel. MENGERINGKAN hal-hal dengan menerapkan layout "[...]" to the controller class only allows one statement effectively. If you have more than two layouts to deal with (say, admin, generic_app, tailored_app), you will experience Render dan / atau redirect disebut beberapa kali dalam kesalahan action` ini; dan Anda tidak punya pilihan selain menggunakan saran ini.
Jerome
1
Jawaban ini adalah yang terbaik, sederhana dan rapi dibandingkan dengan menggunakan metode dengan pernyataan switch atau if.
kev
juga dapat menentukan file erb dan tata letak keduanya: format.html { render 'custom_index', layout: 'application' } dengan cara yang sama.
thatway_3
12

Anda juga dapat menentukan tata letak untuk tindakan menggunakan render:

def foo
  render layout: "application"
end
yottanami
sumber
7

Berbagai cara untuk menentukan tata letak di bawah pengontrol:

  1. Dalam kode berikut, tata letak application_1 disebut di bawah indeks dan menunjukkan tindakan pengontrol Pengguna dan tata letak aplikasi (tata letak default) dipanggil untuk tindakan lain.

    class UsersController < ApplicationController
      layout "application_1", only: [:index, :show]
    end
  2. Dalam kode berikut, tata letak application_1 dipanggil untuk semua tindakan pengontrol Pengguna.

    class UsersController < ApplicationController
       layout "application_1"
    end
  3. Dalam kode berikut, tata letak application_1 dipanggil untuk tindakan uji pengontrol Pengguna saja dan untuk semua tata letak aplikasi tindakan lainnya (default) disebut.

        class UsersController < ApplicationController
          def test
            render layout: "application_1"
          end
        end
puneet18
sumber
5

Presisi:

Cara KERING yang tidak benar-benar berfungsi adalah apa yang Anda lihat di atas, tetapi dengan presisi: tata letak harus sesuai dengan variabel Anda untuk bekerja ("@beberapa"). Sebagai :

def your_action
   @some = foo
   render layout: "your_layout"
end

Dan tidak :

def your_action
   render layout: "your_layout"
   @some = foo
   @foo = some
end

Jika Anda melakukan before_action ... itu tidak akan berfungsi juga.

Semoga ini bisa membantu.

Gregdebrick
sumber