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.