使用 Rails 4 显示 Windows 资源管理器类型树视图的最佳方式

The best way to display Windows Explorer-type tree view with Rails 4

我已经设法生成一些递归代码来绘制 Windows Explorer 类型的树作为 HTML table,基于 Rails 使用的模型祖先 gem。我想知道是否有比字符串连接更优雅的方法来绘制table。我尝试过(认为肯定应该有)但无法调用第二个 erb 部分工作。

这是我的代码,从控制器开始:

def index
  @trees = Tree.all
  @root = Tree.first.root
  @table_string = ''
end

帮手来了:

module TreesHelper

def draw_branch(t)
    ht = ""
    ht << '<tr>'
    ht << "\n\t\t\t"
    ht << '<td class="data" align="left" style="padding-left: '
    ht << ((t.ancestry_depth+1)*15).to_s
    ht << 'px"><img src="assets/icons/folder.gif" class="icon_folder" width="18">'
    ht << (link_to t.name, t).to_s
    ht << '</td>'
    ht << "\n\t\t\t"
    ht << '<td class="data" align="right">'
    ht << number_to_currency(t.value, precision: 0).to_s
    ht << '</td>'
    ht << "\n\t\t\t"
    ht << '<td class="data">'
    ht << t.note
    ht << '</td>'
    ht << "\n\t\t\t"
    ht <<   '<td class="data" align="right">'
    ht << (t.id).to_s
    ht << '</td>'
    ht << "\n\t\t\t"
    ht << '<td class="data" align="right">'
    ht << (t.ancestry_depth).to_s
    ht << '</td>'
    ht << "\n\t\t\t"
    ht << '<td class="data" align="right">'
    ht << (t.has_children?).to_s
    ht << '</td>'
    ht << "\n\t\t\t"
    ht << '<td class="data" align="right">'
    ht << t.parent_id.to_s
    ht << '</td>'
    ht << "\n\t\t"
    ht << '</tr>'
    ht << "\n\t\t"
end

def tree_table(t)
    # render partial: "branch_as_row", object: t    Doesn't work whereas the next line does...
    @table_string << draw_branch(t)
    t.children.each do |tt|
        tree_table(tt)
    end
    @table_string.html_safe
end
end

这是调用辅助函数的原始部分:

<table>
  <thead>
    <tr>
        <th>Folder</th>
        <th>Value</th>
        <th>Note</th>
        <th>ID</th>
        <th>Depth</th>
        <th>Has Children?</th>
        <th>Parent</th>
    </tr>
  </thead>
  <tbody>
    <%= tree_table(@root) %>
  </tbody>
</table>

FWIW,这是不起作用的部分 (_branch_as_row.html.erb):

<tr data-level="<%= t.depth+1%>">
  <td class="data" align="left" style="padding-left: <%=((t.ancestry_depth+1)*10).to_s%>px"><img src="assets/icons/folder.gif" width="14"></td>
  <td class="data" align="right"><%= t.id %></td>
  <td class="data" align="right"><%= t.ancestry_depth %></td>
  <td class="data" align="right"><%= t.has_children? %></td>
  <td class="data"><%= link_to t.name, t %></td>
  <td class="data" align="right"><%= number_to_currency(t.value, precision: 0) %></td>
  <td class="data"><%= t.note %></td>
  <td class="data" align="right"><%= t.parent_id %></td>
</tr>

它会产生 "wrong number of arguments (0 for 1..2)" 错误。

这可能不如它得到的那么好,但是写问题然后再次阅读官方文档的努力让我有了不同的想法,我已经回答了我自己的问题。

这是我现在的看法:

<table id="tree" border="1" cellspacing="0" cellpadding="6" class="table table-hover table-bordered">
    <thead>
        <tr data-level="header" class="header">
            <th>Folder</th>
            <th>ID</th>
            <th>Depth</th>
            <th>Has Children?</th>
            <th>Folder</th>
            <th>Value</th>
            <th>Note</th>
            <th>Parent</th>
        </tr>
    </thead>
    <tbody>
<%= render partial: "branch_as_row", object: @root, as: :t %>
    </tbody>
</table>

这里是(略有改进的)调用自身的部分:

<tr data-level="<%= t.depth+1%>">
  <td class="data" align="left" style="padding-left: <%=((t.ancestry_depth+1)*15).to_s%>px"><img src="assets/icons/folder.gif" width="18" class="icon_folder"><%= link_to t.name, t %></td>
  <td class="data" align="right"><%= t.id %></td>
  <td class="data" align="right"><%= t.ancestry_depth %></td>
  <td class="data" align="right"><%= t.has_children? %></td>
  <td class="data"><%= link_to t.name, t %></td>
  <td class="data" align="right"><%= number_to_currency(t.value, precision: 0) %></td>
  <td class="data"><%= t.note %></td>
  <td class="data" align="right"><%= t.parent_id %></td>
</tr>
<% if t.has_children? %>
  <%= render partial: "branch_as_row", collection: t.children, as: :t %>
<% end %>

比丑陋的字符串连接方法好多了!突破在于了解部分可以调用自身,并使用正确的语法将变量传递给部分。