Rails 视图中的 DRY 视图组件

Posted

技术标签:

【中文标题】Rails 视图中的 DRY 视图组件【英文标题】:DRY view components in Rails views 【发布时间】:2012-06-12 15:53:27 【问题描述】:

我想为我的视图创建抽象组件,这些组件不会透露它们的呈现方式。 该示例是一个选项卡式导航框,例如 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】:

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

必须将外部“组件”传递到块中才能调用内部函数:

      = 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

部分渲染选项卡渲染函数的输出:

    %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 

【讨论】:

以上是关于Rails 视图中的 DRY 视图组件的主要内容,如果未能解决你的问题,请参考以下文章

Rails 中的分析视图

(Rails)从不同视图中的控制器访问方法

Rails 中的高级/基本和智能手机视图

更改 Rails 中的默认视图路径?

从 Rails 中的视图选择或创建

Rails:视图中的两个属性不同的表