Подтвердить что ты не робот

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

Мне иногда приходится добавлять класс в элемент 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), но это не так. Что делают большинство людей?

4b9b3361

Ответ 1

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

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

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

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

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

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

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

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

Ответ 2

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

Проблема стандартного подхода состоит в том, что для этого требуется логика в виде выражений 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 %>">

Вдохновленный реакцией

Этот метод вдохновлен надстройкой под названием classNames (ранее известной как classSet) из фреймворка Facebooks React.

Использование в проектах Rails

В настоящее время функция class_names не существует в Rails, но в этой статье показано, как добавить или реализовать ее в своем проекты.

Ответ 3

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

На макете:

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

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

- content_for :css_class do
    my_specific_class

Вот и все.