我正在使用像这样的单个对象的部分:
#/app/views/people/_person.html.haml
%div[person]
= image_tag person.image
%p.name= person.full_name
%p.location= person.location
...所以我可以将render
方法用于像这样的对象组:
#/app/views/people/index.html.haml
%ul.people
- @people.each do |person|
%li= render person
但是,如果我不止一次渲染一个对象,我会得到两个具有相同id的元素,这不是很好,只是为了验证。有没有办法让上面的单个对象保持局部,然后在调用render时,告诉它为id或者什么加上前缀,以保持id唯一?
我们举一个例子。说,我有一个facebook克隆的种类。在侧栏我有一个你可能会感兴趣的人的列表,在主要区域我有我所有朋友的列表(我目前在人员索引视图中)和标题我有一个人的列表,谁最近尝试联系我这三个集可能会共享一些相同的人,所以我会得到具有相同id的多个元素。我不想像haml那样给我们所有的id person_654
,而是使用括号表示法,我想给边栏中的人员{id} interesting_person_654
,头部中的人{id {{1}并且主要区域中的人(当前视图中的人)标识为lately_calling_person_654
。
我该怎么做?
我想过为命名空间使用一些选项,但是render方法只有4个选项,而命名空间不是其中之一。不过,我可以使用monkeypatching render方法。我宁愿不使用id-prefixing逻辑模糊对象的部分(我甚至不得不在其他所有对象中复制粘贴 - 一点也不好!)。
答案 0 :(得分:0)
来自the docs the Haml’s object reference syntax:
此外,第二个参数(如果存在)将用作id和class属性的前缀。
所以你可以改变:
%div[person]
到(例如):
%div[person, :interesting]
将生成如下内容:
<div class='interesting_person' id='interesting_person_7'>...
然后:
%div[person, :lately_calling]
将创建:
<div class='lately_calling_person' id='lately_calling_person_7'>
答案 1 :(得分:0)
好吧,我找到了解决方案:
当在括号中传递记录时,haml使用记录haml_object_ref
方法来确定要为类使用的值和id前缀。因此,我重写了渲染助手,以便它可以在渲染之前根据它调整这个方法:
# config/initializers/extensions/action_view_extension.rb
#
# (For some reason that is beyond be I could override this method in
# ActionView::Helpers::RenderingHelper, so for not I patched it at class level)
#
class ActionView::Base
alias_method :original_render, :render
def render objects = [], options = {}, *args, &block
class_prefix = options[:class_prefix] || options[:namespace] || options[:as]
records = Array( objects ).select { |object| object.is_a? ActiveRecord::Base }
records.each do |record|
class_name = record.class.to_s.underscore
record.define_singleton_method :haml_object_ref do
[class_prefix, class_name].compact.join( '_' )
end
end
original_render objects, options, *args, &block
end
end
现在我可以在这样的视图中调用render
:
#header
%ul.lately_calling_people
%li = render @lately_calling_people[0], as: 'lately_calling'
%li = render @lately_calling_people[1], as: 'lately_calling'
%li = render @lately_calling_people[2], as: 'lately_calling'
#sidebar
%ul.interesting_people
%li= render @interesting_people[0], as: 'interesting'
%li= render @interesting_people[1], as: 'interesting'
%li= render @interesting_people[2], as: 'interesting'
#main
%div[@person]
@person.name
...
这将生成以下html:
...
<ul class="lately_calling_people"
<li><div class="lately_calling_person" id="lately_calling_person_1">...</div></li>
...
</ul>
...
<ul class="interesting_people"
<li><div class="interesting_person" id="interesting_person_1">...</div></li>
...
</ul>
...
<div class="person" id="person_1">
...
</div>
我可以保持部分简单:
# app/views/people/_person.html.haml
%div[person]
= image_tag person.image
%p.name= person.full_name
%p.location= person.location