在Rails视图中查看DRY组件

时间:2012-06-12 15:53:28

标签: ruby-on-rails views render block dry

我想为我的视图创建抽象组件,但不会透露它们的呈现方式。 该示例是一个标签式导航框,如tabs from bootstrap

在我看来,我想写s.th.像:

    = 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"

然后应该呈现给s.th.像这样:

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

我尝试推迟标签'内容'的呈现失败了。我创建了一个minimal rails app来演示我采用的三种方法。

查看application_helper.rb和welcome#show视图。 做这种事的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

我得到了一些支持并找到了以下解决方案:

必须将外部'component'传递到块中以调用内部函数:

      = 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"

由于我们不需要将块绑定到tab_section实例(之前使用instance_exec完成),我们可以直接生成块。

      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

partial显示标签渲染功能的输出:

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

实现如下:

    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