Cách đơn giản để thêm một lớp có điều kiện vào một phần tử HTML trong một khung nhìn là gì?


103

Đôi khi tôi phải thêm một lớp vào một phần tử html dựa trên một điều kiện. Vấn đề là tôi không thể tìm ra cách làm rõ ràng. Đây là một ví dụ về những thứ tôi đã thử:

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

HOẶC LÀ

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

Tôi không thích cách tiếp cận đầu tiên vì nó trông đông đúc và khó đọc. Tôi không thích cách tiếp cận thứ hai vì việc làm tổ bị vặn chặt. Sẽ rất tuyệt nếu đưa nó vào mô hình, (đại loại là @status.css_class), nhưng điều đó không thuộc về nó. Hầu hết mọi người làm gì?

Câu trả lời:


141

Tôi sử dụng cách đầu tiên, nhưng với cú pháp ngắn gọn hơn một chút:

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

Mặc dù thông thường bạn nên thể hiện thành công với boolean truehoặc ID bản ghi số và thất bại với boolean falsehoặc nil. Bằng cách này, bạn có thể chỉ cần kiểm tra biến của mình:

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

Biểu mẫu thứ hai sử dụng toán ?:tử bậc ba rất hữu ích nếu bạn muốn chọn giữa hai lớp:

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

Cuối cùng, bạn có thể sử dụng các trình trợ giúp thẻ bản ghi của Rail chẳng hạn như div_for, công cụ này sẽ tự động đặt ID và lớp của bạn dựa trên bản ghi mà bạn cung cấp. Cho một Personvới id 47:

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

@Anurag, hãy xem phần này api.rubyonrails.org/classes/ActionController/… . Đồ khá gọn gàng.
maček

cảm ơn vì liên kết @macek. điều này rất giống với cách tôi tạo các phần tử trên MooTools :) gọn gàng và ngăn nắp
Anurag

2
Câu trả lời hay hơn: Tránh toàn bộ mớ hỗn độn và chuyển quan điểm của bạn sang HAML .
Mudgar

2
Hoặc, thậm chí tốt hơn, với SLIM
Dr.Strangelove

4
@ Dr.Strangelove, bạn có thể cho một ví dụ về cách SLIM hoặc HAML sẽ xử lý các lớp có điều kiện một cách thanh lịch hơn không? Còn trong trường hợp có nhiều lớp điều kiện thì sao?
Brendon Muir,

18

Tránh logic trong các khung nhìn

Vấn đề với cách tiếp cận tiêu chuẩn là nó yêu cầu logic ở dạng các ifcâu lệnh hoặc các cụm từ trong khung nhìn. Nếu bạn có nhiều lớp CSS có điều kiện được trộn lẫn với các lớp mặc định, thì bạn cần đặt logic đó vào nội suy chuỗi hoặc thẻ ERB.

Đây là một cách tiếp cận được cập nhật để tránh đặt bất kỳ logic nào vào các chế độ xem:

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

class_string phương pháp

Trình class_stringtrợ giúp lấy một hàm băm với các cặp khóa / giá trị bao gồm chuỗi tên lớp CSSgiá trị boolean . Kết quả của phương thức là một chuỗi các lớp trong đó giá trị boolean được đánh giá là true.

Sử dụng mẫu

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

Các trường hợp sử dụng khác

Trình trợ giúp này có thể được sử dụng trong ERBcác thẻ hoặc với trình trợ giúp Rails chẳng hạn 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 %>

Hoặc / Hoặc các lớp

Đối với các trường hợp sử dụng trong đó một bậc ba là cần thiết (ví dụ @success ? 'good' : 'bad'), hãy chuyển một mảng trong đó phần tử đầu tiên là lớp cho truevà phần tử kia là chofalse

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

Lấy cảm hứng từ React

Kỹ thuật này được lấy cảm hứng từ một tiện ích bổ sung có tên classNames(trước đây gọi là classSet) từ Reactkhung giao diện người dùng của Facebook .

Sử dụng trong các dự án Rails của bạn

Hiện tại, class_nameshàm không tồn tại trong Rails, nhưng bài viết này hướng dẫn bạn cách thêm hoặc triển khai nó vào các dự án của mình.


2

Bạn cũng có thể sử dụng trình trợ giúp content_for, đặc biệt nếu DOM nằm trong một bố cục và bạn muốn đặt lớp css tùy thuộc vào từng phần được tải.

Về bố cục:

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

Về một phần:

- content_for :css_class do
    my_specific_class

Đó là nó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.