Руби, используя блок и параметры, чтобы высушить шаблон - PullRequest
1 голос
/ 15 февраля 2010

У меня есть шаблон в нескольких шаблонах, который повторяется. Код предназначен для отображения набора вкладок и содержимого для каждой вкладки.

Содержимое /app/views/general/_product_groupings.html.erb

<table cellpadding="1" cellspacing="0" class="sub_container clear">
  <tr>
    <% first_visible_tab = true %>
    <% @bundle.groupings.each do |group| %>
      <td id="tab_heading_for_group_<%= group.id %>" class="tab_heading <%= 'selected' if first_visible_tab %>" onclick="show_tab('product_type_<%= group.id %>')"><%= one_liner(group.name) %></td>
      <td></td>
      <% first_visible_tab = false %>
    <% end %>
    <td class="last"></td>
  </tr>
  <tr>
    <td colspan="99" class="tab_content">

      <% first_visible_tab = true %>
      <%# groupings is an array of products %>
      <% @bundle.groupings.each do |group| %>
        <div style="display: <%= (first_visible_tab) ? '' : 'none' %>" id="tab_body_for_group_<%= group.id %>" class="tab_body container_inner">
          <% first_visible_tab = false %>
          <% template = case group.grouping_type 
            when 'selection'
              :product_selection_group
            when 'group'
              :product_optional_group
            when 'product'
              :product_optional_group
            end %>
            <%= render :partial => template.to_s, :locals => {:group => group} %>


        </div>
      <% end %>
    </td>
  <tr>
</table>

Код состоит из нескольких частей. Передается общий параметр, @bundle. Раздел заголовка (строки 1-10):

<table cellpadding="1" cellspacing="0" class="sub_container clear">
  <tr>
    <% first_visible_tab = true %>
    <% @bundle.groupings.each do |group| %>
      <td id="tab_heading_for_group_<%= group.id %>" class="tab_heading <%= 'selected' if first_visible_tab %>" onclick="show_tab('product_type_<%= group.id %>')"><%= one_liner(group.name) %></td>
      <td></td>
      <% first_visible_tab = false %>
    <% end %>
    <td class="last"></td>
  </tr>

В разделе заголовка есть части, которые отличаются каждым кодом места, как это используется: коллекция повторяется, @bundle.groupings. Параметр для show_tab() onclick. Идентификатор вкладки id="tab_heading_for_group_<%= group.id %>".

Ниже заголовка есть область, которую, я считаю, можно получить как блок, реальное содержимое каждой области содержимого вкладки (строки 19-27):

          <% template = case group.grouping_type 
            when 'selection'
              :product_selection_group
            when 'group'
              :product_optional_group
            when 'product'
              :product_optional_group
            end %>
            <%= render :partial => template.to_s, :locals => {:group => group} %>

Чуть выше содержимого - та же коллекция @bundle.groupings.each do ..., повторенная из заголовка.

Я бы очень хотел высушить это. Определив блок с содержимым, которое можно получить внутри вспомогательного метода.

Я думаю, что этот метод должен принимать следующие параметры:

  • id_template
  • onclick_method # возможно с шаблоном для параметра метода onclick
  • коллекция
  • блок для выдачи в области содержимого вкладки

Вопрос в том, как создать вспомогательный метод для получения как блока, так и параметров?

Ответы [ 2 ]

1 голос
/ 15 февраля 2010

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

<%= render :partial => template_for_group(group), :locals => {:group => group} %>

Вы не показываете нам оригинальные шаблоны, но я понимаю, что в них есть общий код. Я был бы склонен это учесть, переместив общий код в свой собственный шаблон (ы) и имея каждый шаблон <% render :partial...> общих битов по мере необходимости.

* Хотя MVC, кажется, требует, чтобы имя шаблона было определено в представлении или помощнике, с точки зрения ОО оно действительно принадлежит группе. Выбери один. Если это больно, это код, который говорит нам, что другой выбор был лучше.

1 голос
/ 15 февраля 2010

Прочитав примеры Coda Hales на блоках , я нашел решение, которое сработало Хитрость заключается в том, чтобы добавить ваши обычные параметры, за которыми следует блок, например:

method_call(params) { |x| x.do_stuff_inside_the_methods_context }

И x получит область действия yield внутри вашего метода. Вот переписать код, использованный в примере. (на данный момент, исключая любые динамические параметры для метода onclick)

Вид:

<% options = {
  :iterator => @bundle.groupings,
  :id_prefix => "group"
} %>
<%= render_tabs(options) { |product|  
  template = case product.grouping_type 
            when 'selection'
              :product_selection_group
            when 'group'
              :product_optional_group
            when 'product'
              :product_optional_group
            end
  render :partial => template.to_s, :locals => {:group => product}

} %>

Помощник:

  def render_tabs(opts, &block)
    collection = opts[:iterator]
    prefix     = opts[:id_prefix]
    buf = %(
    <table cellpadding="1" cellspacing="0" class="sub_container clear">
      <tr>
    )
    first_visible_tab = true 
    collection.each do |iter| 
      classnames = "tab_heading"
      classnames << " selected" if first_visible_tab
      td_id = "#{prefix}_#{iter.id}"
      buf << %(
        <td id="tab_heading_for_#{td_id}" class="#{classnames}" onclick="show_tab('#{td_id}')">#{one_liner(iter.name) }</td>
      )

      first_visible_tab = false 
    end 
    buf << %(<td class="last"></td>
      </tr>
      <tr>
        <td colspan="99" class="tab_content">)

    first_visible_tab = true 
    collection.each do |iter|
      td_id = "#{prefix}_#{iter.id}"
      display_attr = (first_visible_tab) ? '' : ' style="display:none"'
      buf << %(
        <div #{display_attr} id="tab_body_for_#{td_id}" class="tab_body container_inner">
        )
      first_visible_tab = false

      buf << yield(iter)
      buf << %(
        </div>
        )
    end
    buf << %(
        </td>
      <tr>
    </table>
    )

    buf
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...