Який елегантний спосіб умовно додати клас до елемента HTML у поданому вигляді?


103

Іноді доводиться додавати клас до елемента html на основі умови. Проблема в тому, що я не можу зрозуміти чистий спосіб зробити це. Ось приклад того, що я спробував:

<div <%= if @status = 'success'; "class='ok'"; end %>>
   some message here
</div>

АБО

<% if @status == 'success' %>
   <div class='success'>
<% else %>
   <div>
<% end %>
   some message here
</div>

Мені не подобається перший підхід, тому що він переповнений на вигляд і важко читати. Мені не подобається другий підхід, тому що гніздування накручено. Було б добре розмістити його в моделі (щось подібне @status.css_class), але це не належить. Що робить більшість людей?

Відповіді:


141

Я використовую перший спосіб, але з дещо більш складним синтаксисом:

<div class="<%= 'ok' if @status == 'success' %>">

Хоча , як правило , ви повинні представляти успіх булевих trueабо числовий ідентифікатор запису, і невдачі з булевим falseабо nil. Таким чином ви можете просто перевірити свою змінну:

<div class="<%= 'ok' if @success %>">

Друга форма з використанням термінального ?:оператора корисна, якщо ви хочете вибрати між двома класами:

<div class="<%= @success ? 'good' : 'bad' %>">

Нарешті, ви можете скористатись такими помічниками для тегів Record , як div_for, які автоматично встановлять ваш ідентифікатор та клас на основі запису, який ви йому надаєте. З Personідентифікатором 47:

# <div id="person_47" class="person good">
<% div_for @person, class: (@success ? 'good' : 'bad') do %>
<% end %>

@Anurag, перевірте це на api.rubyonrails.org/classes/ActionController/… . Досить акуратні речі.
maček

дякую за посилання @macek. це дуже схоже на те, як я створюю елементи на MooTools :) акуратно і охайно
Anurag

2
Краща відповідь: уникайте всього безладу і перемикайте свої погляди на HAML .
meagar

2
Або, ще краще, до SLIM
Dr.Strangelove

4
@ Dr.Strangelove, чи могли б ви навести приклад того, як SLIM або HAML будуть більш елегантно поводитися з умовними класами? А як щодо кількох умовних класів?
Брендон Муїр

18

Уникання логіки у поглядах

Проблема стандартного підходу полягає в тому, що він вимагає логіки у вигляді ifвисловлювань чи тернарів у погляді. Якщо у вас є кілька умовних класів CSS, змішаних з класами за замовчуванням, то вам потрібно ввести цю логіку в строкову інтерполяцію або тег ERB.

Ось оновлений підхід, який дозволяє уникнути будь-якої логіки у поглядах:

<div class="<%= class_string(ok: @success) %>">
   some message here
</div>

class_string метод

class_stringПомічник приймає хеш з парами ключ / значення , що складаються з імен рядків класу CSS і логічних значень . Результатом методу є рядок класів, де булеве значення оцінюється на істинне.

Використання зразка

class_names(foo: true, bar: false, baz: some_truthy_variable)
# => "foo baz"

Інші випадки використання

Цей помічник може використовуватися в ERBтегах або з такими помічниками Rails, як link_to.

<div class="<%= class_string(ok: @success) %>">
   some message here
</div>

<% div_for @person, class: class_string(ok: @success) do %>
<% end %>

<% link_to "Hello", root_path, class: class_string(ok: @success) do %>
<% end %>

Або / або класи

Для випадків використання, коли потрібен потрійний (наприклад @success ? 'good' : 'bad'), передайте масив, де перший елемент є класом для, trueа другий дляfalse

<div class="<%= [:good, :bad] => @success %>">

Натхненний React

Ця методика натхненна додатком під назвою classNames(раніше відомим як classSet) з Reactфронтальної бази Facebook .

Використання у ваших проектах Rails

На даний момент class_namesфункція не існує в Rails, але ця стаття показує, як додати або реалізувати її у своїх проектах.


2

Ви також можете використовувати помічник content_for, особливо якщо DOM розташований у макеті та ви хочете встановити клас css залежно від частково завантаженого.

На макеті:

%div{class: content_for?(:css_class) ? yield(:css_class) : ''}

На частково:

- content_for :css_class do
    my_specific_class

Це все.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.