Was ist eine elegante Möglichkeit, einem HTML-Element in einer Ansicht eine Klasse bedingt hinzuzufügen?

103

Ich muss gelegentlich eine Klasse zu einem HTML-Element hinzufügen, basierend auf einer Bedingung. Das Problem ist, dass ich keinen sauberen Weg finden kann, es zu tun. Hier ist ein Beispiel für das, was ich ausprobiert habe:

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

ODER

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

Ich mag den ersten Ansatz nicht, weil er überfüllt aussieht und schwer zu lesen ist. Ich mag den zweiten Ansatz nicht, weil die Verschachtelung vermasselt ist. Es wäre schön, es in das Modell aufzunehmen (so etwas wie @status.css_class), aber das gehört nicht dorthin. Was machen die meisten Leute?

Ryeguy
quelle

Antworten:

141

Ich benutze den ersten Weg, aber mit einer etwas prägnanteren Syntax:

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

Normalerweise sollten Sie jedoch Erfolg mit boolescher trueoder einer numerischen Datensatz-ID und Misserfolg mit boolescher falseoder darstellen nil. Auf diese Weise können Sie einfach Ihre Variable testen:

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

Ein zweites Formular mit dem ternären ?:Operator ist nützlich, wenn Sie zwischen zwei Klassen wählen möchten:

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

Schließlich können Sie die Datensatz-Tag-Helfer von Rail verwenden, z. B. div_for, mit denen Ihre ID und Klasse basierend auf dem von Ihnen angegebenen Datensatz automatisch festgelegt werden. Gegeben ein Personmit ID 47:

# <div id="person_47" class="person good">
<% div_for @person, class: (@success ? 'good' : 'bad') do %>
<% end %>
meagar
quelle
@ Anurag, schau dir das an api.rubyonrails.org/classes/ActionController/… . Ziemlich ordentliches Zeug.
Maček
danke für den link @macek. Dies ist sehr ähnlich wie ich Elemente auf MooTools erstellen :) ordentlich und ordentlich
Anurag
2
Bessere Antwort: Vermeiden Sie das ganze Durcheinander und wechseln Sie Ihre Ansichten zu HAML .
Meagar
2
Oder noch besser zu SLIM
Dr.Strangelove
4
@ Dr.Strangelove, könnten Sie ein Beispiel geben, wie SLIM oder HAML bedingte Klassen eleganter behandeln würden? Wie wäre es mit mehreren bedingten Klassen?
Brendon Muir
18

Vermeiden von Logik in den Ansichten

Das Problem beim Standardansatz besteht darin, dass Logik in Form von ifAnweisungen oder Ternären in der Ansicht erforderlich ist . Wenn Sie mehrere bedingte CSS-Klassen mit Standardklassen gemischt haben, müssen Sie diese Logik in eine Zeichenfolgeninterpolation oder ein ERB-Tag einfügen.

Hier ist ein aktualisierter Ansatz, bei dem keine Logik in die Ansichten eingefügt wird:

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

class_string Methode

Der class_stringHelfer verwendet einen Hash mit Schlüssel / Wert-Paaren, die aus CSS-Klassennamenzeichenfolgen und booleschen Werten bestehen . Das Ergebnis der Methode ist eine Zeichenfolge von Klassen, bei denen der boolesche Wert als wahr ausgewertet wird.

Beispielnutzung

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

Andere Anwendungsfälle

Dieser Helfer kann innerhalb von ERBTags oder mit Rails-Helfern wie z 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 %>

Entweder / Oder Klassen

Übergeben Sie für Anwendungsfälle, in denen ein Ternär erforderlich wäre (z. B. @success ? 'good' : 'bad'), ein Array, in dem das erste Element die Klasse für trueund das andere für istfalse

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

Inspiriert von React

Diese Technik ist inspiriert von einem Add-On namens classNames(früher bekannt als classSet) aus dem ReactFront-End-Framework von Facebook .

Verwendung in Ihren Rails-Projekten

Derzeit ist die class_namesFunktion in Rails nicht vorhanden. In diesem Artikel erfahren Sie jedoch, wie Sie sie in Ihre Projekte einfügen oder in diese implementieren können.

Carlos Ramirez III
quelle
2

Sie können auch den Helfer content_for verwenden, insbesondere wenn sich das DOM in einem Layout befindet und Sie die CSS-Klasse abhängig vom teilweise geladenen festlegen möchten.

Auf dem Layout:

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

Zum Teil:

- content_for :css_class do
    my_specific_class

Das ist es.

acmoune
quelle