Ruby-on-rails 有条件地将类添加到视图中的 HTML 元素的优雅方式是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2626936/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's an elegant way to conditionally add a class to an HTML element in a view?
提问by ryeguy
I occasionally have to add a class to an html element based on a condition. The problem is I can't figure out a clean way of doing it. Here's an example of the stuff I've tried:
我有时必须根据条件向 html 元素添加一个类。问题是我想不出一个干净的方法来做到这一点。这是我尝试过的东西的一个例子:
<div <%= if @status = 'success'; "class='ok'"; end %>>
some message here
</div>
OR
或者
<% if @status == 'success' %>
<div class='success'>
<% else %>
<div>
<% end %>
some message here
</div>
I don't like the first approach because it's crowded looking and hard to read. I don't like the second approach because the nesting is screwed up. It'd be nice to put it in the model, (something like @status.css_class), but that doesn't belong there. What do most people do?
我不喜欢第一种方法,因为它看起来很拥挤且难以阅读。我不喜欢第二种方法,因为嵌套被搞砸了。将它放在模型中会很好,(类似于@status.css_class),但这不属于那里。大多数人做什么?
回答by meagar
I use the first way, but with a slightly more succinct syntax:
我使用第一种方式,但语法稍微简洁一点:
<div class="<%= 'ok' if @status == 'success' %>">
Though usually you should represent success with boolean trueor a numeric record ID, and failure with boolean falseor nil. This way you can just test your variable:
虽然通常你应该用布尔值true或数字记录 ID表示成功,用布尔值false或nil. 这样你就可以测试你的变量:
<div class="<%= 'ok' if @success %>">
A second form using the ternary ?:operator is useful if you want to choose between two classes:
?:如果您想在两个类之间进行选择,则使用三元运算符的第二种形式很有用:
<div class="<%= @success ? 'good' : 'bad' %>">
Finally, you can use Rail's record tag helperssuch as div_for, which will automagically set your ID and class based on the record you give it. Given a Personwith id 47:
最后,您可以使用 Rail 的记录标签助手,例如div_for,它会根据您提供的记录自动设置您的 ID 和类。给定一个Personid 为 47 的:
# <div id="person_47" class="person good">
<% div_for @person, class: (@success ? 'good' : 'bad') do %>
<% end %>
回答by Carlos Ramirez III
Avoiding logic in the views
避免视图中的逻辑
The problem with the standard approach is that it requires logic in the form of ifstatements or ternaries in the view. If you have multiple conditional CSS classes mixed with default classes, then you need to put that logic into a string interpolation or ERB tag.
标准方法的问题在于它需要if视图中语句或三元组形式的逻辑。如果您有多个条件 CSS 类与默认类混合,那么您需要将该逻辑放入字符串插值或 ERB 标记中。
Here's an updated approach that avoids putting any logic into the views:
这是一种避免将任何逻辑放入视图的更新方法:
<div class="<%= class_string(ok: @success) %>">
some message here
</div>
class_stringmethod
class_string方法
The class_stringhelper takes a hash with key/value pairs consisting of CSS class name stringsand boolean values. The result of the method is a string of classes where the boolean value evaluated to true.
该class_string助手负责与包括键/值对的哈希CSS类名字符串和布尔值。该方法的结果是一串类,其中布尔值评估为 true。
Sample Usage
示例用法
class_names(foo: true, bar: false, baz: some_truthy_variable)
# => "foo baz"
Other Use Cases
其他用例
This helper can be used within ERBtags or with Rails helpers such as link_to.
这个助手可以在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 %>
Either/Or Classes
要么/要么类
For use cases where a ternary would be necessary (e.g. @success ? 'good' : 'bad'), pass an array where the first element is the class for trueand the other is for false
对于需要三元组的用例(例如@success ? 'good' : 'bad'),传递一个数组,其中第一个元素是 for 的类,true另一个是 forfalse
<div class="<%= [:good, :bad] => @success %>">
Inspired by React
灵感来自 React
This technique is inspired by an add-on called classNames(formerly known as classSet) from Facebook's Reactfront-end framework.
此技术的灵感来自 Facebook前端框架中名为classNames(以前称为classSet)的附加组件React。
Using in your Rails projects
在 Rails 项目中使用
As of now, the class_namesfunction does not exist in Rails, but this articleshows you how to add or implement it into your projects.
截至目前,class_namesRails 中不存在该功能,但本文将向您展示如何将其添加或实现到您的项目中。
回答by acmoune
You can also use the content_for helper, especially if the DOM is located in a layout and you want to set the css class depending on the partial loaded.
您还可以使用 content_for 帮助器,尤其是当 DOM 位于布局中并且您想根据加载的部分设置 css 类时。
On the layout:
在布局上:
%div{class: content_for?(:css_class) ? yield(:css_class) : ''}
On the partial:
在部分:
- content_for :css_class do
my_specific_class
That is it.
这就对了。

