Rails:分离两个非常相似的视图的最佳方法是啥?

Posted

技术标签:

【中文标题】Rails:分离两个非常相似的视图的最佳方法是啥?【英文标题】:Rails: What is the best way to seperate two very similar views?Rails:分离两个非常相似的视图的最佳方法是什么? 【发布时间】:2010-01-12 12:51:38 【问题描述】:

我有一个控制器,它有两个动作:“show”、“show_modify”。它们有非常相似但略有不同的视图,即 show_modify 有不同的 div 类,有额外的链接/按钮等等。

据我所知,有几种方法可以在 Rails 中解决这个问题:

    为两者制作一个模板,然后在里面添加条件:

    <% if param[:action]=="show_modify"> <% ... %> <% end %>
    

    然而有这么多的差异,这看起来很丑陋和重复,这也是某种违反政教分离的行为(我不是 MVC 专家......)

    部分方式:为每个显示不同的元素创建两个部分,每个操作一个。视图看起来像这样:

    # show_modify
    render :partial '_general_stuff'
    render :partial => '_blabla_show_modify'
    
    # show  
    render :partial => '_general_stuff'  
    render :partial => '_blabla_show'  `  
    

    然而这会违反 DRY,因为有重叠的元素。我可以继续制作更多的子部分,但基本上都是海龟——如果你不想重复自己,最终你必须去 if/else。

    与当地人的部分:

    if show  
         render :partial = '_blabla', :locals => :bckgrnd => 'blue', :button => 'yes' ....
    

    但这是另一种解决方案....

还有更好的选择吗? content_for 也许?我有点像 Rails 菜鸟+,所以我可能完全错过了一些东西....

【问题讨论】:

【参考方案1】:

根据您的描述,这两个视图似乎不太相似,在整个完整视图中都有各种例外。因此,您的许多 if 语句或部分不起作用的问题。

难道不能以更好地匹配的方式重构您的视图吗?例如,保持 div 类名相同并根据您的视图切换 CSS。然后使用部分视图方法可能会更好。特别是如果您还将链接(提交按钮?)移到该局部视图之外并将其放入 show_modify 视图中。

【讨论】:

【参考方案2】:

如果差异很小,您可以使用您的第一个想法,但我宁愿做一些帮助:

def show_modify?
  param[:action] == "show_modify"
end

然后在视图中:

<% if show_modify? %>
  some html
<% end %>
...
<%= link_to "something", some_path if show_modify? %>

等等。

如果是 div 类,我会使用辅助方法来生成类名:

def set_class
  return "first_class" if show_modify?
  "second_class"
end

【讨论】:

我不知道 构造。它的可读性非常强,并且产生的混乱更少......谢谢!【参考方案3】:

尝试将对象扩展为视图模型。这在 ASP.NET MVC 中很常见,当您想用与业务域无关的东西来扩展域对象时。

class User < ActiveRecord::Base
  # id, integer
  # first_name, string
  # last_name, string
  # only put the business-y stuff here. validations, etc.
end

class ShowUserViewModel < User
  def background_color
    "#0000ff"
  end

  def template
    "show"
  end
end

class EditUserViewModel < User

  def background_color
    "#00ff00"
  end

  def template
    "show_modify"
  end
end

从您的控制器中,根据所采取的操作,返回适当的对象。视图模型仍然是“用户”,但它们补充了视图所需的更多信息。这确实可以让很多iffor 结构不可见。

【讨论】:

这不是一个很干净的方法,因为模型应该被用来抓取数据(例如从数据库中),所以它可以在视图中使用。更简洁的解决方案是使用 Helper 方法并根据视图动态地将其功能添加到 Controller【参考方案4】:

我也有类似的情况。我正在考虑将我的观点分成两个完全不同的观点。如果两个视图随着年龄的增长而变得越来越不同是有意义的,这可能是最好的选择,因为这两个新视图将完全解耦。如果您希望 showshow_modify 之间的大部分视图保持不变,那么这种方法可能不太有用...

【讨论】:

以上是关于Rails:分离两个非常相似的视图的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

在非常相似的组件的情况下,进行条件渲染的最佳方法是啥?

确定不再需要哪些源文件的最佳方法是啥?

如果 JS 可能被禁用,Rails 4 link_to :delete 的最佳方法是啥?

在数据导入期间处理两个非常相似的类的最佳方法

在 Rails 中存储应用程序特定配置的最佳方式是啥?

在使用相似对象的多个服务中重用相似方法的最佳方法是啥?