Qual è un modo elegante per aggiungere in modo condizionale una classe a un elemento HTML in una vista?


103

A volte devo aggiungere una classe a un elemento html in base a una condizione. Il problema è che non riesco a trovare un modo pulito per farlo. Ecco un esempio delle cose che ho provato:

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

O

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

Non mi piace il primo approccio perché è affollato e difficile da leggere. Non mi piace il secondo approccio perché l'annidamento è avvitato. Sarebbe bello metterlo nel modello, (qualcosa di simile @status.css_class), ma non ci appartiene. Cosa fa la maggior parte delle persone?

Risposte:


141

Uso il primo modo, ma con una sintassi leggermente più succinta:

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

Sebbene di solito dovresti rappresentare il successo con booleano trueo un ID record numerico e il fallimento con booleano falseo nil. In questo modo puoi semplicemente testare la tua variabile:

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

Una seconda forma che utilizza l' ?:operatore ternario è utile se si desidera scegliere tra due classi:

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

Infine, puoi utilizzare gli helper dei tag dei record di Rail come div_for, che imposteranno automaticamente l'ID e la classe in base al record che gli dai. Dato a Personcon id 47:

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

@Anurag, dai un'occhiata a api.rubyonrails.org/classes/ActionController/… . Roba abbastanza carina.
— maček

grazie per il link @macek. questo è molto simile a come creo elementi su MooTools :) pulito e ordinato
— Anurag

2
Risposta migliore: evita tutto il casino e cambia le tue opinioni su HAML .
— meagar

2
O, ancora meglio, a SLIM
— Dr.Stranamore

4
@ Dr.Strangelove, potresti fornire un esempio di come SLIM o HAML gestiscono le classi condizionali in modo più elegante? Che ne dici nel caso di più classi condizionali?
— Brendon Muir

18

Evitando la logica nelle viste

Il problema con l'approccio standard è che richiede logica sotto forma di ifaffermazioni o ternari nella vista. Se hai più classi CSS condizionali mescolate con classi predefinite, devi inserire quella logica in un'interpolazione di stringhe o in un tag ERB.

Ecco un approccio aggiornato che evita di inserire alcuna logica nelle visualizzazioni:

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

class_string metodo

L' class_stringhelper prende un hash con coppie chiave / valore costituite da stringhe di nomi di classi CSS e valori booleani . Il risultato del metodo è una stringa di classi in cui il valore booleano viene valutato su true.

Utilizzo di esempio

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

Altri casi d'uso

Questo helper può essere utilizzato all'interno dei ERBtag o con gli helper di Rails come 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 %>

O / O Classi

Per i casi d'uso in cui sarebbe necessario un ternario (ad esempio @success ? 'good' : 'bad'), passa un array in cui il primo elemento è la classe per truee l'altro è perfalse

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

Ispirato da React

Questa tecnica è ispirata da un componente aggiuntivo chiamato classNames(precedentemente noto come classSet) dal Reactframework front-end di Facebook .

Utilizzo nei tuoi progetti Rails

Al momento, la class_namesfunzione non esiste in Rails, ma questo articolo mostra come aggiungerla o implementarla nei propri progetti.


2

Puoi anche usare l'helper content_for, soprattutto se il DOM si trova in un layout e vuoi impostare la classe css in base al parziale caricato.

Sul layout:

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

Sul parziale:

- content_for :css_class do
    my_specific_class

Questo è tutto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.