如何在Rails视图中循环并打印多维数组?

时间:2022-12-10 07:18:31

I'm using the ancestry gem, and would like to print out an entire tree into a table. The object I'm working with is groups, so it'd look something like this.

我正在使用祖先宝石,并想打印整个树到一个表格。我处理的对象是组,它看起来是这样的。

Group A
|__ Group A 1
    |__ Group A 1 A
|__ Group A 2
    |__ Group A 2 A
    |__ Group A 2 B
Group B
Group C
|__ Group C 1

Typically, I'd create a method and call itself within the loop, but that would seem to break MVC convention. Within the view, how would I output the object/hash?

通常,我将创建一个方法并在循环中调用自己,但这似乎违反了MVC约定。在视图中,如何输出对象/散列?

Note: Ancestry has a method to convert the ActiveModel group to a hash, so that is an option rather than iterating through the ActiveModel object itself.

注意:Ancestry有一个将ActiveModel组转换为散列的方法,所以这是一个选项,而不是遍历ActiveModel对象本身。

3 个解决方案

#1


3  

There's no reason you can't use a loop within your view, and that's exactly the way you'd want to do it:

你没有理由不能在视图中使用循环,这正是你想要的方式:

<% @groups.each do |group| %>
  <!-- Render stuff -->
  <% group.groups.each do |child| %>
    <!-- Render child stuff -->
  <% end %>
<% end %>

It may be a lot easier to manage if you do this using partials instead:

如果你用偏置法来处理,可能会容易得多:

# view.html.erb
<% render partial: 'group', collection: @groups, as: :group %>

# _group.html.erb
<!-- Render stuff -->
<% render partial: 'first_child', collection: group.groups, as: :group %>

Check out the Rendering Collections section of the Rails guide on Layouts and Rendering for some more info.

查看Rails指南中有关布局和呈现的呈现集合部分,了解更多信息。


EDIT: If you need to handle an unknown level of nesting, partials would work here too. You can even track the depth if you want. Say you wanted to display them using nested ul elements:

编辑:如果您需要处理未知级别的嵌套,分区也可以在这里工作。你甚至可以跟踪深度,如果你想的话。假设您希望使用嵌套的ul元素显示它们:

# _group.html.erb
<% content_tag :li, class: "depth-#{depth}" do %>
  <!-- Any output needed for the group itself -->
  <% unless group.group.empty? %>
    <ul>
      <%= render partial "group", collection: group.groups, as: :group,
              locals: { depth: depth+1 } %>
    </ul>
  <% end %>
<% end %>

# In your view file
<ul>
  <% render partial "group", collection: @groups, as: :group,
         locals: { depth: 0 } %>
</ul>

#2


2  

Create a proc. This is a recursion problem.

创建一个proc。这是一个递归问题。

array_printer = Proc.new do |set| 
  set.map {|elem| (elem.is_a? Array) ? array_printer(elem) : "<td>#{elem}</td>" }
end

puts array_printer master_set

#3


1  

I'd just write a helper to do it.

我只要写一个助手就行了。

def render_tree(groups)
  content_tag(:ul) do
    groups.map do |group|
      content_tag(:li) do
        content_tag(:div, group.name, class: "groupname") +
        render_tree(group.children)
      end
    end.join
  end
end

Then in your view:

然后在你的观点:

<%= render_tree @your_tree %>

Style as desired.

根据需要的风格。

#1


3  

There's no reason you can't use a loop within your view, and that's exactly the way you'd want to do it:

你没有理由不能在视图中使用循环,这正是你想要的方式:

<% @groups.each do |group| %>
  <!-- Render stuff -->
  <% group.groups.each do |child| %>
    <!-- Render child stuff -->
  <% end %>
<% end %>

It may be a lot easier to manage if you do this using partials instead:

如果你用偏置法来处理,可能会容易得多:

# view.html.erb
<% render partial: 'group', collection: @groups, as: :group %>

# _group.html.erb
<!-- Render stuff -->
<% render partial: 'first_child', collection: group.groups, as: :group %>

Check out the Rendering Collections section of the Rails guide on Layouts and Rendering for some more info.

查看Rails指南中有关布局和呈现的呈现集合部分,了解更多信息。


EDIT: If you need to handle an unknown level of nesting, partials would work here too. You can even track the depth if you want. Say you wanted to display them using nested ul elements:

编辑:如果您需要处理未知级别的嵌套,分区也可以在这里工作。你甚至可以跟踪深度,如果你想的话。假设您希望使用嵌套的ul元素显示它们:

# _group.html.erb
<% content_tag :li, class: "depth-#{depth}" do %>
  <!-- Any output needed for the group itself -->
  <% unless group.group.empty? %>
    <ul>
      <%= render partial "group", collection: group.groups, as: :group,
              locals: { depth: depth+1 } %>
    </ul>
  <% end %>
<% end %>

# In your view file
<ul>
  <% render partial "group", collection: @groups, as: :group,
         locals: { depth: 0 } %>
</ul>

#2


2  

Create a proc. This is a recursion problem.

创建一个proc。这是一个递归问题。

array_printer = Proc.new do |set| 
  set.map {|elem| (elem.is_a? Array) ? array_printer(elem) : "<td>#{elem}</td>" }
end

puts array_printer master_set

#3


1  

I'd just write a helper to do it.

我只要写一个助手就行了。

def render_tree(groups)
  content_tag(:ul) do
    groups.map do |group|
      content_tag(:li) do
        content_tag(:div, group.name, class: "groupname") +
        render_tree(group.children)
      end
    end.join
  end
end

Then in your view:

然后在你的观点:

<%= render_tree @your_tree %>

Style as desired.

根据需要的风格。