You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phoenix/Elixir:如何用递归渲染树形分类下拉列表?

树形分类下拉列表渲染问题

问题背景

我有一个支持层级分类的数据库表(同表内一个分类可作为另一个分类的子分类),表结构示例如下:

category_idcategory_nameparent_id
1Vocabularynil
2Animals1
3Food1
4Grammarnil
5Mammals2

希望在分类创建表单中渲染出如下格式的树形下拉列表:

Vocabulary
 - Animals
    - Mammals
 - Food
Grammar

已在控制器中获取到嵌套结构的分类数据:

[
 %{cat: "Vocabulary", subcat: [
   %{cat: "Animals", subcat: [
     %{cat: "Mammals", subcat: []}
   ]},
   %{cat: "Food", subcat: []}
 ]}, 
 %{cat: "Grammar", subcat: []}
]

项目未使用LiveView,不确定如何在模板中实现该树形下拉的渲染,同时想了解是否有更优的处理方案。


解决方案

1. 模板递归渲染(结构清晰,推荐)

通过定义局部模板实现递归处理嵌套分类,直观展示层级缩进:

步骤1:创建局部模板 _category_option.html.eex

<%= for category <- categories do %>
  <option value="<%= category.cat %>" style="padding-left: #{indent_level * 15}px;"><%= category.cat %></option>
  <%= render "_category_option.html.eex", categories: category.subcat, indent_level: indent_level + 1 %>
<% end %>

步骤2:在主表单模板中调用

<select name="category[parent_id]">
  <option value="">-- 选择父分类 --</option>
  <%= render "_category_option.html.eex", categories: @categories, indent_level: 0 %>
</select>
  • 用indent_level控制每层级的左内边距,层级越深缩进越大
  • 也可以用Phoenix的option_tag辅助函数替代原生<option>标签

2. 预格式化选项文本(轻量高效)

在控制器中提前处理所有分类,生成带缩进标记的文本,直接渲染扁平选项列表:

控制器数据处理

defp format_categories(categories, indent \\ "") do
  Enum.flat_map(categories, fn category ->
    [
      %{name: "#{indent}#{category.cat}", value: category.cat},
      format_categories(category.subcat, indent <> "  - ")
    ]
  end)
end

# 在action中调用生成格式化数据
formatted_categories = format_categories(@raw_categories)

模板渲染

<select name="category[parent_id]">
  <option value="">-- 选择父分类 --</option>
  <%= for cat <- @formatted_categories do %>
    <option value="<%= cat.value %>"><%= cat.name %></option>
  <% end %>
</select>

这种方式会生成和示例完全一致的文本格式,适合层级较少的场景。


更优处理方案建议

  • 存储结构优化:如果分类层级深或数据量大,可改用嵌套集(Nested Set)或闭包表(Closure Table)模式存储,能更高效地查询树形结构,避免多次递归查询
  • 缓存优化:分类数据变更频率低,可将结构化后的树形数据缓存,减少每次请求的处理开销
  • 前端交互增强:若需要展开/折叠等交互,可在基础渲染完成后用纯JS实现动态效果,无需依赖LiveView

内容的提问来源于stack exchange,提问作者Akanksha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 03:36:01