Какой элегантный способ условно добавить класс в элемент HTML в представлении? - PullRequest
92 голосов
/ 13 апреля 2010

Мне иногда приходится добавлять класс к элементу html на основе условия. Проблема в том, что я не могу придумать, как это сделать. Вот пример того, что я пробовал:

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

OR

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

Мне не нравится первый подход, потому что он выглядит многолюдно и плохо читается. Мне не нравится второй подход, потому что вложенность нарушена. Было бы неплохо поместить это в модель (что-то вроде @status.css_class), но это не относится к этому. Что делает большинство людей?

Ответы [ 3 ]

125 голосов
/ 13 апреля 2010

Я использую первый способ, но с немного более лаконичным синтаксисом:

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

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

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

Вторая форма, использующая троичный оператор ?:, полезна, если вы хотите выбрать один из двух классов:

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

Наконец, вы можете использовать Rails помощники по тегам записей , такие как div_for, которые автоматически установят ваш ID и класс на основе записи, которую вы ему дадите. Дано Person с идентификатором 47:

# <div id="person_47" class="person good">
<% div_for @person, class: (@success ? 'good' : 'bad') do %>
<% end %>
14 голосов
/ 18 января 2017

Избежание логики в представлениях

Проблема стандартного подхода заключается в том, что он требует логики в виде if операторов или троичных выражений в представлении. Если у вас есть несколько условных CSS-классов, смешанных с классами по умолчанию, вам нужно поместить эту логику в строковую интерполяцию или тег ERB.

Вот обновленный подход, позволяющий избежать введения какой-либо логики в представления:

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

class_string метод

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

Пример использования

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 голосов
/ 03 мая 2017

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

На макете:

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

На частичном:

- content_for :css_class do
    my_specific_class

Вот и все.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...