0

我正在对单个对象使用部分,如下所示:

#/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 的元素。我不想给他们所有的 id person_654,就像 haml 对括号符号所做的那样,我想给侧边栏中的interesting_person_654人 id ,标题中的lately_calling_person_654人 id 和主要区域中的人(来自当前查看) id person_654

我该怎么做?

我想为命名空间使用一些选项,但渲染方法只有 4 个选项,命名空间不是其中之一。不过,我会很好地修改渲染方法。我宁愿不使用 id 前缀逻辑来掩盖对象的局部(我什至必须将其复制粘贴到所有其他对象的局部——一点都不好!)。

4

2 回答 2

0

文档中,Haml 的对象引用语法

此外,第二个参数(如果存在)将用作 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'>
于 2013-11-04T01:44:17.990 回答
0

好吧,我找到了一个解决方案:

当传递括号中的记录时,haml 使用 recordshaml_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
于 2013-11-07T07:10:39.283 回答