Подтвердить что ты не робот

Какое изящное решение для несвязанных представлений в веб-фреймворках MVC?

У меня возникла проблема со следующей проблемой в Rails и ASP.Net MVC. Часто на странице есть несколько виджетов функциональности, но одно действие контроллера должно отображать страницу. Позвольте мне проиллюстрировать:

Скажем, у меня есть обычный сайт электронной коммерции, а меню сделано из категорий, а на странице отображается группа продуктов.

Для продуктов, скажем, у меня есть действие над контроллером, которое выглядит примерно так:

def product_list
     @products = Products.find_by_category(:name => 'lawnmowers')
end

И у меня есть макет с чем-то вроде

<div id="menu"><%= render :partial => 'menu' %></div>
<div id="content"><%= yield %></div>

Продукты имеют вид...

<%= render :partial => 'product', :collection => @products %>

(обратите внимание, что я не видел представления продукта как несущественного)

И в меню есть частичный...

<% Category.each {|c| %>
   <%= render :partial => 'menu_node', :locals => { :category => c } %>
<% } %>

У меня есть проблема с "Category.each.do" в представлении. Я получаю данные в представлении, в отличие от использования переменных, которые были установлены и связаны в контроллере. И это может быть легко более сложный вызов метода, создающий меню.

Решения, которые я рассмотрел, следующие:

- Просмотр базового класса модели, который знает, как получить различные части данных. Но вы могли бы получить один из них для каждого концептуального "раздела" сайта.
- локальная переменная, которая заполняется в верхней части каждого метода (нарушает DRY) - то же самое, но в вызове before_filter

Ни один из них не кажется мне очень изящным. Я не могу не смотреть на эту проблему и думать, что презентатор MVP для представления (а не экран) является более элегантным решением.

ASP.Net MVC оказывает действие (отличное от rails render: action), которое делает это, но я не уверен, что я думаю об этом решении.

Мысли? Рекомендации по решению?

Добавлено Примечание: Ответы, представленные до сих пор, являются хорошими предложениями. И они применимы к примеру, который я дал, где меню, вероятно, присутствует в каждом макете, и явно является вторичным по отношению к данным продукта.

Однако, что, если явно нет гражданина второго сорта? Сайты типа портала обычно имеют несколько несвязанных виджетов, в которых каждый из них важен.

Например, Что делать, если на этой странице отображались тенденции погоды, с виджетами для температуры, влажности и осадков (и каждая из них отличается от модели и вида вида).

4b9b3361

Ответ 1

В рельсах нам нравится иметь концепцию тонких контроллеров, толстых моделей. Поэтому я думаю, что вы правы, чтобы не хотеть иметь переменные, установленные в контроллере.

Кроме того, чтобы позже включить более сложный метод, я рекомендую сделать что-то вроде:

/app/controllers/application_controller.rb

before_filter :add_menu_nodes

def add_menu_nodes
  @menu_nodes = Category.menu_nodes(current_user)
end

/app/views/layouts/application.html.erb

<%= render :partial=>:menu, :locals=>{:categories=>@menu_nodes} %>

/app/models/category.rb

def self.menu_nodes(current_user)
  Category.all.order(:name)
end

Таким образом, в будущем вы можете обновить Category.menu_nodes с более сложным решением, основанным на текущем пользователе, если вам нужно.

Ответ 2

Простите меня, если я мясник Ruby (или неправильно понял ваш вопрос), но что не так с

class section_helper
    def menu( section )
        // ...
        menuBuiltAbove
    end
end

в представлении

<%= section_helper.menu( 'section' ) %>

?