Phoenix LiveView 0.18 の構文をいじっています。
具体的にはこれ。
:if and :for
It is a syntax sugar for <%= if .. do %> and <%= for .. do %> that can be used in regular HTML, function components, and slots.
For example in an HTML tag:
<table id="admin-table" :if={@admin?}> <tr :for={user <- @users}> <td><%= user.name %> </tr> <table>
この形の構文は、従来の Phoenix でも、ふだん仕事で使っている Ruby on Rails でも出てこない形なので、今でもこれを見るとむずむずする感じがあるのですが、入れ子が浅くなることで、反復する要素を実際の深さのレベルで書けるという点はわかりやすくてよいですね。
と、いうわけで。 LiveView 0.18 でQRコードを表示させてみました。
defmodule MyAppWeb.QrLive do use MyAppWeb, :live_view def mount(_, _, socket) do {:ok, assign(socket, view_box: "", size: 0, cells: [])} end def render(assigns) do ~H""" <form phx-change="change"><textarea name="qr[text]" /></form> <svg viewBox={@view_box} xmlns="http://www.w3.org/2000/svg" fill="black"> <rect x="0" y="0" width={@size} height={@size} fill="white" /> <rect :for={{x, y} <- @cells} x={x} y={y} width="1" height="1" /> </svg> """ end def handle_event("change", %{"qr" => %{"text" => text}}, socket) do socket = case QRCode.create(text) do {:ok, %QRCode.QR{matrix: matrix}} -> size = length(matrix) cells = for {row, y} <- Enum.with_index(matrix), {cell, x} <- Enum.with_index(row), cell == 1, do: {x, y} assign(socket, view_box: "0 0 #{size} #{size}", size: size, cells: cells) _ -> socket end {:noreply, socket} end end
実行例。