我拔出我的头发,因为我知道这可能是我错过的一些非常小的东西,但我只是想在成功提交表单后清除表单 - 创建一个要点没有任何问题。
这是我的简单 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.heex 文件:
<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>
表单工作正常,因为填充所有字段后数据将持久保存到 postgres 数据库。如果缺少字段,我们会收到验证错误。但我就是无法在成功提交后清除表格。我认为我通过创建一个空白的 Gist 变更集并将其分配给 form 做了正确的事情,但由于某种原因这不起作用。
简短的答案是,您还需要在表单上使用
phx-change
来保持 html 输入值和分配的变更集值相同。
将您的打开表单元素标签更改为:
<.form for={@form} phx-submit="create" phx-change="change">
并将其添加到您的实时视图中:
def handle_event("change", params, socket) do
changeset = Gists.change_gist(%Gist{}, params["gist"])
socket = assign(socket, :form, to_form(changeset))
{:noreply, socket}
end
通过这些更改,您将随着 html 输入的变化而更新表单。
这应该使“重置表单”按您的预期工作。
要理解为什么会这样,想象一下表单是否使用您的代码重置了。
如果您的代码确实重置了表单,则这意味着 HTML“始终”使用指定的表单值来显示输入中的值。如果它像这样工作,那么每次用户输入内容时,它都会被删除,因为表单分配没有改变! 通过保持分配的表单值和 html 输入同步,LiveView“知道”可以重置表单值。