Componentes de vista DRY en vistas Rails

Quiero crear componentes abstractos para mis vistas, que no revelen la forma en que se representarán. El ejemplo es un cuadro de navegación con pestañas como el pestañas de bootstrap

En mi opinión, quiero escribir algo. me gusta:

    = tab_section(self) do
      - tab 'tab1' do
        %p tab1 content
        = link_to example_var, "#top"
      - tab 'tab2' do
        %p tab2 content
        = link_to 'http://example.com', "#top"

que luego debe ser rendido a s.th. como esto:

        <ul>
          <li>tab1</li>
          <li>tab2</li>
        </ul>
        <div class='content'>
          <div class='tab'>
            <p>tab1 content</p>
            <a href='#top'>this could also be an @var from the controller</a>
          </div>
          <div class='tab'>
            <p>tab2 content</p>
            <a href='#top'>http://example.com</a>
          </div>
        </div>

Todos mis intentos de diferir la representación de la pestaña 'contenido' fallaron. creé un aplicación de rieles mínimos demostrando los tres enfoques que tomé.

Eche un vistazo a application_helper.rb y la vista welcome#show. ¿Cuál es la forma correcta de hacer tal cosa?

preguntado el 12 de junio de 12 a las 16:06

1 Respuestas

Recibí ayuda y encontré la siguiente solución:

El 'componente' externo debe pasarse al bloque para llamar a la función interna:

      = tab_section2 do |section|
        - section.tab 'tab1' do
          %p tab1 content
          = link_to example_var, "#top"
        - section.tab 'tab2' do
          %p tab2 content
          = link_to 'http://example.com', "#top"

Dado que no necesitamos vincular el bloque a la instancia de tab_section (anteriormente se hizo con instance_exec), podemos generar el bloque directamente.

      def tab_section2(&blk)
        raise "Y U NO SUPPLY block?" unless block_given?
        ts = TabSection2.new(self, self)
        yield(ts)
        render :partial => '/tab2', locals: {section: ts}
      end

El parcial representa la salida de la función de representación de pestañas:

    %ul
      - section.tabs.each do |tab|
        %li= tab.name
    .content
      - section.tabs.each do |tab|
        .tab
          = tab.render.html_safe

Que se implementa de la siguiente manera:

    class Tab2

      attr_reader :name, :blk
      def initialize(name, context, &blk)
        @context = context
        @name = name
        @blk = blk 
      end 

      def render
        @context.capture_haml(&@blk)
      end 
    end 

    class TabSection2
      attr_reader :tabs

      def initialize(context)
        @context = context
        @tabs = []
      end 

      def tab(name, &blk)
        raise "Y U NO SUPPLY block?" unless block_given?
        @tabs << Tab2.new(name, @context, &blk)
      end 
    end 

Respondido el 13 de junio de 12 a las 13:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.