Как обрабатывать переменную «status» в шаблонах Phoenix - PullRequest
0 голосов
/ 01 марта 2019

Я пытаюсь сделать что-то подобное ниже в моем шаблоне eex:

<% current_production_date = nil %>
<%= for widget <- @widgets do %>
  <%= if (current_production_date != widget.production_date) do %>
    <!-- ... output a new date header and re-assign current production_date -->
    <% current_production_date = widget.production_date %>
  <% end %>
  <%= render "_widget.html", widget: widget %>
<% end %>

Это не сработает, поскольку внешняя переменная "current_production_date" не может быть переназначена внутри понимания.Это похоже на обычный сценарий, так что я думаю, что есть прямой способ сделать это ... Я просто не могу понять это ... любые намеки очень ценятся!

Ответы [ 3 ]

0 голосов
/ 01 марта 2019

Хотя ответ @ Badu технически верен, он [самоуверенный] не полностью идиоматический эликсир, поскольку имеет дублирование кода и использует [опрометчиво] неправильную абстракцию для представления кусков данных.

То, что у вас есть, это буквально список кусков, так что вам, вероятно, нужно: Enum.chunk_while/4.

chunk_fun = fn 
  widget, [] ->
    {:cont, [widget]}
  #                  ⇓⇓                                ⇓⇓  PATTERN MATCH!
  %{production_date: pd} = widget, [%{production_date: pd} | _] = prev ->
    {:cont, [widget | prev]}
  widget, acc ->
    {:cont, Enum.reverse(acc), []}
  end
after_fun = fn
  [] -> {:cont, []}
  acc -> {:cont, Enum.reverse(acc), []}
end
widgets = Enum.chunk_while(@widgets, [], chunk_fun, after_fun)

Теперь в widgets у вас есть куски из @widgets, сгруппированы по дате.Давайте выведем их:

for [%{production_date: date} | _] = chunk <- widgets do
  # output the header with the date
  for widget <- chunk do
    # render the widget
  end
end

Я не тестировал этот код, но он должен работать как есть.

0 голосов
/ 01 марта 2019

Спасибо за предложения, в итоге я получил предложение, полученное на форуме Elixir ... используя group_by:

<%= for {date, widgets}
  <- Enum.group_by(@widgets, fn(x) -> DateTime.to_date(x.production_date) end)
  |> Enum.sort(fn({date1, _widget1}, {date2, _widget2}) ->
    case Date.compare(date2, date1) do
      :lt -> true
      _ -> false
    end
  end) do %>
  <%= render "_date_header.html", date: date %>
  <%= for widget <- widgets do  %>
    <%= render "_widget.html", widget: widget %>
  <% end %>
<% end %>

В итоге я извлек это в представление, так как оно немногонеприятно, когда это прямо в шаблоне.

0 голосов
/ 01 марта 2019

Вы можете использовать Enum.reduce/3 для накопления результата и вывода результата после.

<% 
current_production_date = nil
{result, _}  = 
Enum.reduce(@widgets, {[], current_production_date}, 
fn %{production_date: production_date} = widget, {acc, current_date} ->
    if product_date != current_date do
      output = "<h1>output a new date header and re-assign current production_date</h1>"
      {[output, Phoenix.View.render_to_string(PageView, "widget.html", widget: widget) 
        |acc], production_date}
    else
        {[Phoenix.View.render_to_string(PageView, "widget.html", widget: widget) |acc], current_date} 
    end
end) %>

<%= for w <- Enum.reverse(result) do %>
    <%= raw(w) %>
<% end %>
...