在视图之外重构代码

Posted

技术标签:

【中文标题】在视图之外重构代码【英文标题】:Refactoring code out of the view 【发布时间】:2011-06-20 10:26:34 【问题描述】:

我有以下显示事件的视图代码,以及通知用户今天、昨天或过去一周是否发生了以下事件的标题。

这一切都很好,但我更愿意将它重构到视图之外,我不能把它放在帮助器中,因为它需要在循环迭代之间维护变量状态。知道如何整理吗?谢谢

<% displayed_week_already = false %>
<% displayed_yesterday_already = false %>
<% displayed_today_already = false %>

<% @events.each do |event| %>

  <%= event.title &>

  <% if (Time.now - 1.week) > event.created_at && !displayed_week_already %>
    <% displayed_week_already = true %>
    Events in past week
  <% elsif (Time.now - 1.day) > event.created_at && (Time.now - 2.day) < event.created_at && !displayed_yesterday_already %>
    <% displayed_yesterday_already = true %>
    Events yesterday
  <% elsif (Time.now - 1.day) < event.created_at && !displayed_today_already %>
    <% displayed_today_already = true %>
    Events in past day
  <% end %>

<% end %>

预期的输出是:

过去一天的事件 约翰创作了一篇新文章 丹评论文章 1 苏删除第 2 条

昨天的活动 苏创建了一篇新文章

过去一周的活动 卡罗尔升职 Dan 发表了一篇新文章

【问题讨论】:

【参考方案1】:

我可能会执行以下操作。我忽略了模型本身定义的实现方法。

现有视图

<%= render "events", :title => "Events in past day",  :events => from_today(@events) %>
<%= render "events", :title => "Events yesterday",    :events => from_yesterday(@events) %>
<%= render "events", :title => "Events in past week", :events => from_this_week(@events) %>

_events.html.erb

<% if events.present? %>
  <%= title %>
  <% events.each do |event| %>
    <%= event.title %>
  <% end %>
<% end %>

app/helpers/event_display_helper.rb

module EventDisplayHelper
  def from_today(events)
    events.select|x| x.happened_today?
  end

  def from_yesterday(events)
    events.select|x| x.happened_yesterday?
  end

  def from_this_week(events)
    events.select|x| x.happened_this_week_before_yesterday?
  end
end

【讨论】:

【参考方案2】:

你可以很容易地在模型中使用命名范围来做到这一点(我假设是 Rails 3,因为这是我最了解的)。您需要自己定义它们,但它们非常简单。

@last_week = @event.last_week
@yesterday = @event.yesterday
@today = @event.today

然后只需遍历视图中的每个组。应该让它更干净,你不需要那么多逻辑,因为它是它真正所属的地方。

【讨论】:

谢谢斯蒂芬,我确实考虑过这一点,但如果不是不可能的话,它会让分页变得很尴尬。 好的,您期望的实际输出是什么?也许我们可以想出一些对你有用的东西,让分页更容易。 在您的示例中,分页会放在哪里?我倾向于建议通过 Ajax 加载每个事件块,并单独对每个块进行分页以支持这一点。 假设每页有 10 个事件,如果第一天有 11 个事件,您将在第 1 页看到“过去一天的事件”,在第 2 页看到“昨天的事件”。这只是一个时间添加一些标题以添加一些上下文。它完全按照我现在想要的方式工作,这不是一个优雅的解决方案 嗯......在那种情况下,我不确定有什么方法可以让它更干净(无论如何,我的知识有限)。希望其他人能参与进来!

以上是关于在视图之外重构代码的主要内容,如果未能解决你的问题,请参考以下文章

业务重构

核心数据重构

与多个视图共享数据 - 重构

重构.改善既有代码的设计7在对象之间搬移特性(如何优化类)

Nine——tornado操作之用户图片上传和展示功能代码的重构(由开始的面向编程的思维方式转变为面向对象的思维方式进行代码的重构!)

ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室 代码重构使用反射工厂解耦