【问题标题】:Presenter Pattern演示者模式
【发布时间】:2020-01-22 05:09:35
【问题描述】:

我经常看到模式 1 最常用于 Rails 演示者。

1) 为什么演示者需要视图上下文?

2) 在模式 1 和 2 之间,模式 2 似乎更容易,因为您不需要用块包装整个代码。为什么不经常使用这个?使用这个有缺点吗? vs 模式 1?

3) 对于模式 3,为什么人们根本不使用这种模式?

演讲者

module ApplicationHelper
  def present(model, presenter_class=nil)
    klass = presenter_class || "#{model.class}Presenter".constantize
    presenter = klass.new(model, self)
    yield(presenter) if block_given?
  end
end

class UserPresenter < ApplicationPresenter
  def full_name
    "#{@model.first_name} #{@model.last_name}"
  end

  def birth_year
    return nil unless @model.birthdate
    @model.birthdate.year
  end

  def nickel_per_year
    return nil unless @model.birthdate
    difference = Date.today.year - birth_year
    @view.number_to_currency(difference * 0.05)
  end
end

class ApplicationPresenter < SimpleDelegator
  def initialize(model, view)
    @model, @view = model, view
    super(@model)
  end
end

模式 1


在带有块的视图中使用演示者助手

查看

<% @users.each do |u| %>
  <% present(u) do |user| %>
    <tr>
      <td><%= user.full_name %></td>
      <td><%= user.email %></td>
      <td><%= user.birthdate %></td>
      <td><%= user.birth_year %></td>
      <td><%= user.nickel_per_year %></td>
      <td><%= link_to 'Show', user %></td>
      <td><%= link_to 'Edit', edit_user_path(user) %></td>
      <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
  <% end %>
<% end %>

模式 2


在视图中使用演示者并设置变量

查看

<% @users.each do |u| %>
  <% user = UserPresenter.new(user, self) %>
    <tr>
      <td><%= user.full_name %></td>
      <td><%= user.email %></td>
      <td><%= user.birthdate %></td>
      <td><%= user.birth_year %></td>
      <td><%= user.nickel_per_year %></td>
      <td><%= link_to 'Show', user %></td>
      <td><%= link_to 'Edit', edit_user_path(user) %></td>
      <td><%= link_to 'Destroy', user, method: :delete, data: { confirm: 'Are you sure?' } %></td>
    </tr>
<% end %>

模式 3


在控制器中使用演示者,假设您可以使用这样的解决方案传递视图上下文。 https://github.com/endofunky/oprah

用户控制器

def show
  @user = UserPresenter.new(User.find(params[:id]), view_context)
end

def index
   @users = Users.all.map {|user|  UserPresenter.new(user, view_context) }
end

【问题讨论】:

  • Presenter 模式有很多缺点,尽管这个问题可能会因为基于意见而被关闭,可能是read this post

标签: ruby-on-rails ruby ruby-on-rails-5 presenter


【解决方案1】:

1) 为什么演示者需要视图上下文?

视图上下文允许访问查看帮助,如link_to 等,如果不包含必要的模块,您通常无法在演示者中访问这些帮助。例如,您可能会这样做:

def deactivate_button
   view_context.link_to('Deactivate', '...', disabled: deactivated?)
end

2) 在模式 1 和 2 之间,模式 2 似乎更容易,因为您不需要用块包装整个代码。为什么不经常使用这个?使用这个有缺点吗? vs 模式 1?

除了您可以访问未呈现用户和呈现用户的块之外,没有任何实际区别。但是您需要访问未呈现的用户吗?我不会说,我更愿意使用非阻塞选项。

3) 对于模式 3,为什么人们根本不使用这种模式?

他们会这样做,并且最好在控制器中设置一个 var 而不是在视图中设置。

【讨论】:

  • 视图上下文添加了哪些模块?如果我想手动添加它们而不传递视图上下文?
  • ActionView::Helpers::UrlHelper这样的模块
猜你喜欢
  • 2020-06-11
  • 2010-10-05
  • 2014-10-31
  • 2016-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
相关资源
最近更新 更多