肯定已经提出了这个问题,但我没有找到。
我经常被迫在视图中编写类似的代码:
<div class="<%= c ? 'my_class' : 'my_other_class' %>">
<div class="<%= 'my class' if c %>">
<div<%= c ? 'class="my_class"' : 'id="my_div"' %>>
或(更漂亮的方式,但不太可读):
<% div_inner = capture do %>
...
<% end %>
<% if c %>
<div class="my_class"><%= div_inner %></div>
<% else %>
<div><%= div_inner %></div>
<% end %>
最后一个:
<% div_inner = capture do %>
...
<% end %>
<%= content_tag(:div, div_inner, (c ? { :class => "my_class" } : {})) %>
我发现所有这些解决方案在语法上都很脏。我相信有一个更好的方式。但女巫? 欢迎您自己的经历。
答案 0 :(得分:4)
你认为有更好的方法是正确的。将条件逻辑置于视图中违背了MVC的精神。根据您的示例,您可以使用简单的帮助程序方法,而不是您可能在Web上阅读的任何更复杂的实现。
你可以创建一个看起来像这样的辅助方法
def conditional_div(condition, true_class, false_class)
content_tag :div, class: (condition ? true_class : false_class) do
yield if block_given?
end
end
然后在您的视图中,您可以像这样使用新的帮助
<%= conditional_div(c, 'my_class', '') do %>
<p>Your content</p>
<% end %>
答案 1 :(得分:1)
我不是content_tag :div
的忠实粉丝,因为我发现它使代码难以维护并且很难追踪。在partials,helpers和javascript之间,可能需要一个小时来查找如何将类分配给元素。
无论如何,在这种情况下
<div class="<%= c ? 'my_class' : 'my_other_class' %>">
我通常只是尝试将类名构建为对象的属性。比方说,根据活动或取消
然后我的div看起来像
<div class="first-class <%= record.state %>">.....</div>
然后我的CSS有.active{}
和.cancelled{}
定义。它没有摆脱所有erb标签,但它肯定使它们更简单。你最终会得到一些奇怪的CSS类名,但我发现它比凌乱的erb代码更容易处理。
还有,
<div<%= c ? 'class="my_class"' : 'id="my_div"' %>>
我看起来不对劲。 id和class在语义上是不同的东西,不应该以这种方式混合。调试非常困难。
答案 2 :(得分:0)
根据您正在做的事情,如果条件c
有点“全局”(例如当前页面的名称或语言,或者用户当前是否已登录,或者是早上还是晚上。 ...),将它们设置为body
元素的CSS类是有意义的,因此输出如下所示:
<body class="is_home_page lang_en is_logged_in">
并在CSS中完成剩下的工作:
body.is_home_page .classname { color: red }
body.is_sub_page .classname { color: green }
整体HTML可以更容易阅读。