2010-02-14 3 views
1

두 개의 템플릿에 반복되는 패턴이 있습니다. 이 코드는 각 탭에 대한 탭 및 내용 집합을 렌더링하는 데 사용됩니다. /app/views/general/_product_groupings.html.erbRuby 블록과 params를 사용하여 템플릿을 말리십시오.

<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입니다. 헤더 섹션

<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, 반복시 컬렉션이 헤더 부 (라인 1-10)가있다. show_tab() onclick의 매개 변수입니다. 탭 id="tab_heading_for_group_<%= group.id %>"의 ID입니다.

  <% 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} %> 

단지 콘텐츠 상기

가있다 : 헤더 아래

내가 각 탭 콘텐츠 영역의 실제 콘텐츠 (라인 19-27)를 블록으로 수득 될 수있다라고 생각하는 영역이있다 머리 부분에서 같은 컬렉션 @bundle.groupings.each do ... 반복.

나는 이것을 정말 많이 마시고 싶습니다. 도우미 메서드 내에서 생성 될 수있는 내용으로 블록을 정의합니다.

  • 컬렉션
  • 블록 안쪽 수득 할 온 클릭 메소드의 파라미터에 대한 패턴

    • id_template
    • onclick_method #perhaps :

      는 I이 방법은 다음 PARAMS을한다고 생각 탭의 내용 영역

    질문 : 어떻게하면 도우미 메소드를 만들어서 bot h 블록과 params?

  • 답변

    1

    Coda Hales examples on blocks을 읽은 후 효과가있는 해결책을 발견했습니다. 트릭과 같이 블록 다음에 평소 매개 변수를 추가하는 것입니다

    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 
    
    +0

    템플릿에서 헬퍼 또는 컨트롤러로 가장 조금 더 많은 HTML을 이동해야 할 때마다 디자인이 안쪽으로 보이기 시작합니다. 나는 더 나은 디자인을 사용할 수 있고, 더 적은 일로 꽤있을 것으로 생각한다. –

    +0

    나는 블록과 params를 구현하는 것과 관련된 특정 질문에 대한 대답으로 이것을 받아 들였다. 그러나 Wayne Conrads가 내가 설명한 것과 비슷한 상황을 구현하면 대답을 생각해보십시오. –

    1

    내가 여기서 할 거라고있는 유일한 방법은 제거하는 것입니다 case 문은 코드에서 템플릿 이름을 도우미 *에 두어 뷰가 다른 템플릿을 사용하도록 요청할 수 있도록합니다.

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

    원본 템플릿을 표시하지 않지만 일반적인 코드가 있습니다.나는 공통 코드를 자신의 템플릿으로 옮기고 각 템플릿을 필요한만큼 공통 비트 <% render :partial...>을 갖는 것으로 생각하고있다.

    * MVC에서보기 또는 도우미에서 템플릿 이름을 결정해야하지만 OO 관점에서는 실제로 그룹에 속합니다. 하나를 선택. 아프면 다른 선택이 더 좋다는 것을 알려주는 코드입니다.

    +0

    코드 개발을보고 답을 생각한 후에 마침내 질문에 가장 근접한 내 대답을 수락하기로 결정했습니다. 그러나 도우미 대신 부분 템플릿을 구현하는 것이 가장 좋은 전략이며, 더 명확한 코드를 제공합니다. –

    관련 문제