3

这个问题肯定已经被问过了,但我没有找到。

我经常被迫在视图中编写这样的代码:

  • <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" } : {})) %>

我发现所有这些解决方案在语法上都很脏。我相信有更好的方法。但是女巫?欢迎您亲身体验。

4

3 回答 3

4

你假设有更好的方法是正确的。将条件逻辑放入视图中是违反 MVC 精神的。根据您的示例,您可以使用简单的辅助方法,而不是您可能在网络上阅读的任何更复杂的实现。

您可以创建一个看起来像这样的辅助方法

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 %>
于 2013-03-15T13:43:54.763 回答
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 在语义上是不同的东西,不应该以这种方式混合。这变得非常难以调试。

于 2013-03-15T15:05:41.170 回答
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 更易于阅读。

于 2013-03-15T13:35:29.463 回答