Tim*_*han 11 model-view-controller asp.net-mvc design-patterns ruby-on-rails
我在Rails和ASP.Net MVC中遇到了以下问题.通常页面上有多个功能小部件,但是应该有一个控制器动作呈现页面.让我说明一下:
假设我有一个普通的电子商务网站,菜单由类别组成,而页面则显示一组产品.
对于产品,假设我在控制器上有一个动作,看起来像:
def product_list
@products = Products.find_by_category(:name => 'lawnmowers')
end
Run Code Online (Sandbox Code Playgroud)
我有一个类似的布局
<div id="menu"><%= render :partial => 'menu' %></div>
<div id="content"><%= yield %></div>
Run Code Online (Sandbox Code Playgroud)
产品有一个观点......
<%= render :partial => 'product', :collection => @products %>
Run Code Online (Sandbox Code Playgroud)
(注意我已经忽略了产品视图无关紧要)
菜单有部分......
<% Category.each {|c| %>
<%= render :partial => 'menu_node', :locals => { :category => c } %>
<% } %>
Run Code Online (Sandbox Code Playgroud)
我遇到问题的一行是视图中的"Category.each.do".我在视图中获取数据,而不是使用在控制器中设置和绑定的变量.它可以很容易地成为一个产生菜单的更复杂的方法调用.
我考虑过的解决方案是:
- 一个知道如何获取各种数据的视图模型基类.但是,对于网站的每个概念性"部分",您最终可能会得到其中一个.
- 填充在每个方法顶部的局部变量(违反DRY) - 同样的事情,但是在before_filter调用中
这些对我来说都不是很优雅.我不禁看看这个问题,并认为每个视图(不是屏幕)的MVP演示者是一个更优雅的解决方案.
ASP.Net MVC具有渲染操作(与rails render:action不同),它确实解决了这个问题,但我不确定我对该解决方案的看法.
思考?解决方案建议
补充说明: 到目前为止提供的答案都是很好的建议.它们适用于我给出的示例,其中每个布局中都可能存在菜单,并且显然是产品数据的次要选项.
但是,如果显然没有二等公民呢?门户类型站点通常具有多个不相关的小部件,其中每个小部件都很重要.
例如,如果此页面显示天气趋势,温度,湿度和降水的小部件(每个都是不同的模型和视图类型),该怎么办?
在 Rails 中,我们喜欢有薄控制器、厚模型的概念。所以我认为你不想在控制器中设置变量是正确的。
另外,为了稍后启用更复杂的方法,我建议执行以下操作:
/应用程序/控制器/application_controller.rb
before_filter :add_menu_nodes
def add_menu_nodes
@menu_nodes = Category.menu_nodes(current_user)
end
Run Code Online (Sandbox Code Playgroud)
/app/views/layouts/application.html.erb
<%= render :partial=>:menu, :locals=>{:categories=>@menu_nodes} %>
Run Code Online (Sandbox Code Playgroud)
/app/models/category.rb
def self.menu_nodes(current_user)
Category.all.order(:name)
end
Run Code Online (Sandbox Code Playgroud)
这样,将来您可以根据当前用户的需要,使用更复杂的解决方案更新 Category.menu_nodes 。
| 归档时间: |
|
| 查看次数: |
362 次 |
| 最近记录: |