我想为我的视图创建抽象组件,但不会透露它们的呈现方式。 该示例是一个标签式导航框,如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视图。 做这种事的正确方法是什么?
答案 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