Elixir LiveView表单提交后无法重置问题求助
问题:Phoenix LiveView表单提交成功后无法清空
表单可正常提交并创建Gist(数据能持久化到PostgreSQL数据库),缺失字段时也会触发验证错误,但成功提交后无法清空表单。尝试过创建空白Gist Changeset并重新赋值给form,但并未生效。
代码文件:create_gist_live.ex
defmodule ElixirGistWeb.CreateGistLive do use ElixirGistWeb, :live_view import Phoenix.HTML.Form alias ElixirGist.{Gists, Gists.Gist} def mount(_params, _session, socket) do socket = assign( socket, form: to_form(Gists.change_gist(%Gist{})) ) {:ok, socket} end def handle_event("create", params, socket) do case Gists.create_gist(socket.assigns.current_user, params["gist"]) do #passing params["gist"] is so so necessary. I was stuck for a day just passing params at first {:ok, _gist} -> changeset = Gists.change_gist(%Gist{}) socket = socket |> put_flash(:info, "Gist created successfully.") |> assign(:form, to_form(changeset)) {:noreply, socket} {:error, %Ecto.Changeset{} = changeset} -> {:noreply, assign(socket, :form, to_form(changeset))} end end end
对应的HTML模板文件
<div class="em-gradient flex items-center justify-center"> <h1 class="font-brand font-bold text-3xl text-white"> Instantly share Elixir code, notes, and snippets. </h1> </div> <.form for={@form} phx-submit="create"> <div class="justify-center px-28 w-full space-y-4 mb-10"> <.input field={@form[:description]} placeholder="Gist description.." autocomplete="off"/> <div> <div class="flex p-2 items-center bg-emDark rounded-t-md border"> <div class="w-[300px] mb-2"> <.input field={@form[:name]} placeholder="Filename including extension..." autocomplete="off"/> </div> </div> <.input field={@form[:markup_text]} type="textarea" placeholder="Insert code..." spellcheck="false" autocomplete="off" /> </div> <div class="flex justify-end"> <.button class="create_button">Create gist</.button> </div> </div> </.form>
解决方法
问题根源是Phoenix LiveView默认会保留用户的表单输入状态,即使你替换了空白Changeset,它也可能复用旧状态。以下是两种有效解决方式:
方式1:给to_form添加reset: true选项
修改handle_event成功分支的代码,明确告诉LiveView重置表单状态:
{:ok, _gist} -> changeset = Gists.change_gist(%Gist{}) socket = socket |> put_flash(:info, "Gist created successfully.") |> assign(:form, to_form(changeset, reset: true)) # 新增reset: true {:noreply, socket}
方式2:客户端触发表单重置(备选)
如果方式1不生效,可以通过推送事件让客户端执行重置:
- 修改HEEX模板的表单,添加
phx-success监听:
<.form for={@form} phx-submit="create" phx-success="reset-form"> <!-- 原有表单内容不变 --> </.form> <script> window.addEventListener('phx:reset-form', () => { document.querySelector('form').reset(); }); </script>
- 在LiveView的成功分支推送重置事件:
{:ok, _gist} -> changeset = Gists.change_gist(%Gist{}) socket = socket |> put_flash(:info, "Gist created successfully.") |> assign(:form, to_form(changeset)) |> push_event("reset-form", %{}) # 推送重置事件 {:noreply, socket}
内容的提问来源于stack exchange,提问作者Duck Dodgers
相关产品推荐
相关产品推荐

