代码之家  ›  专栏  ›  技术社区  ›  Mitkins Noldorin

Phoenix-在模板中分组详细项目

  •  -1
  • Mitkins Noldorin  · 技术社区  · 9 年前

    鉴于以下情况:

    [
      {"2016-05-06T08:59:50", "Woke up"},
      {"2016-05-06T09:30:20", "Ate breakfast"},
      {"2016-05-07T01:48:10", "Went to bed"}
    ]
    

    我想在网页中显示(以上)详细信息行,但按天分组:

    <h1>6 May 2016</h1>
    8:59 - Woke up
    9:30 - Ate breakfast
    
    <h1>7 May 2016</h1>
    1:48 - Went to bed
    

    在菲尼克斯,使用模板的最佳方式是什么?在模板中呈现之前,最好将Ecto查询的结果转换为Controller中的父/子数据结构吗?如果是,那么我会在模板中使用嵌套循环吗?

    1 回复  |  直到 9 年前
        1
  •  2
  •   Gazler    9 年前

    您可以使用 Enum.group_by/3 :

    Enum.group_by(dates, fn {date, _} -> Ecto.Date.cast!(date) end)
    

    这将导致以下结果:

    %{#Ecto.Date<2016-05-06> => [{"2016-05-06T09:30:20", "Ate breakfast"},
      {"2016-05-06T08:59:50", "Woke up"}],
      #Ecto.Date<2016-05-07> => [{"2016-05-07T01:48:10", "Went to bed"}]}
    

    然而,映射不是有序数据类型,因此您可能应该在使用 Enum.sort/1 :

    Enum.group_by(dates, fn {date, _} -> Ecto.Date.cast!(date) end) |> Enum.sort()
    
    [{#Ecto.Date<2016-05-06>,
      [{"2016-05-06T09:30:20", "Ate breakfast"},
       {"2016-05-06T08:59:50", "Woke up"}]},
     {#Ecto.Date<2016-05-07>, [{"2016-05-07T01:48:10", "Went to bed"}]}]
    

    模板应类似于:

    <%= for {date, events} <- @dates do %>
      <h1><%= date %></h1>
      <%= for event <- Enum.reverse(events) do %>
        <%= event %>
      <% end %>
    <% end %>
    

    请注意,我们将列表颠倒过来,这是因为 group_by 将通过在列表前面加上标题来构建列表。