I assume, that if I implement handle_event("change_form"...) and
modify my current_struct() on each change, then the change would also
be applied on UI. But I would like to modify the actual struct only on
submit, and in the meantime to get the data from the @form
在<代码>()中,你可以从你的结构中提取这些数值,并将这些数值储存在册,然后这些数值可用于填入<编码>。 在用户对表格进行改动后,将打电话到handle_event(>
,handle_event(
)将接受表格中所用的数值。
In addition, inside mount()
you can save your original struct in the socket, then in handle_event()
you will be able to access any values from the struct that you need. After the user hits Submit, handle_event()
will receive the final values entered into the form, which you can use to update the original struct.
例如:
#========= Your struct code =======
defmodule MyApp.MyStruct do
defstruct some_integer: 3,
some_string: "",
some_bool: true
end
defmodule MyApp.Context do
alias MyApp.MyStruct
def current_struct() do
%MyStruct{}
end
end
#================================
defmodule DemoWeb.DemoLive do
use DemoWeb, :live_view
def mount(_params, _session, socket) do
orig_struct = MyApp.Context.current_struct()
o_int = orig_struct.some_integer
o_string = orig_struct.some_string
o_bool = orig_struct.some_bool
initial_form_data = %{
"input_int" => o_int,
"input_string" => o_string,
"input_bool" => o_bool
}
socket = assign(socket,
my_struct: orig_struct,
current_int: o_int,
current_string: o_string,
current_bool: o_bool,
my_form: to_form(initial_form_data)
)
{:ok, socket}
end
def render(assigns) do
# When you write:
#
# <.form for={@my_form} ... >
# <.input field={@my_form[:input_int] } ... />
#
# that creates an input element with the type atribute set to "text",
# the name and id attributes set to "input_int", and the value
# attribute set to the value corresponding to the "input_int" key in the form data
# given to to_form(). If there s no key for "input_int" in the form data, then there
# won t be a value attribute--unless you explicitly set the value attribute. Explicitly
# setting the value attribute takes precedence over any form data given to to_form().
#
~H"""
<div>
<%= "current integer: #{@current_int}, current string: #{@current_string},
current bool: #{@current_bool}" %>
</div>
<div>
<%= "original integer: #{@my_struct.some_integer}, original string: #{@my_struct.some_string},
original bool: #{@my_struct.some_bool}" %>
</div>
<div>-------</div>
<div>-------</div>
<.form for={@my_form} phx-change="changed" phx-submit="save">
<.input label="Some integer:"
field={@my_form[:input_int] }
value={@current_int}
/>
<.input label="Some string:"
field={@my_form[:input_string]}
value={@current_string}
/>
<.input label="Some bool:"
field={@my_form[:input_bool]}
value={@current_bool}
/>
<.button>Submit</.button>
</.form>
"""
end
def handle_event("changed",
%{"input_int" => entered_int,
"input_string" => entered_string,
"input_bool" => entered_bool
},
socket) do
#Do something with entered_int, entered_string, entered_bool, e.g. change
#the values that the <div> uses:
socket = assign(socket,
current_int: entered_int,
current_string: entered_string,
current_bool: entered_bool
)
{:noreply, socket}
end
def handle_event("save",
%{"input_int" => entered_int,
"input_string" => entered_string,
"input_bool" => entered_bool
},
socket) do
start_struct = socket.assigns.my_struct
updated_struct = %{start_struct | some_integer: entered_int,
some_string: entered_string,
some_bool: entered_bool}
#Do something with updated_struct, e.g.:
IO.inspect(updated_struct, label: "[ME]updated struct:")
{:noreply, socket}
end
end
这里是活语页面所看的例子:
在模板中撰写:
field={@my_form[:input_int]
本职能定义:
def handle_event("save",
%{"input_int" => entered_int,
"input_string" => entered_string,
"input_bool" => entered_bool
},
socket) do
pattern/em>。 • 绘制地图,如:
iex(2)> function_argument = %{"a" => 10, "b" => 20}
%{"a" => 10, "b" => 20}
iex(3)> %{"a" => a_val} = function_argument
%{"a" => 10, "b" => 20}
iex(4)> a_val
10
iex(5)> %{"b" => b_val, "a" => a_val} = function_argument
%{"a" => 10, "b" => 20}
iex(6)> b_val
20
iex(7)> a_val
10
你们也可以这样做:
def handle_event("save", payload, socket) do
%{"input_int" => entered_int,
"input_string" => entered_string,
"input_bool" => entered_bool} = payload
该法典:
updated_struct = %{start_struct | some_integer: entered_int,
some_string: entered_string,
some_bool: entered_bool}
利用special syntax,用于更新地图或结构(如用于清单的Syntax)。 特别辛迪加确保这些钥匙已经列入地图,因此,错失行为不会给地图增添新的钥匙。
Watch the output in a terminal window, and you ll be able to see what happens when you change an input field or hit the Submit button.
When I try to use input_value(), then I always get nil, even if
inspect(form) shows that both some_integer and some_bool have the
values that I expect them to have.
我获得的唯一途径是<代码>nil。 我请我发言:
Phoenix.HTML.Form.input_value(my_form, :input_int)
如果钥匙在<代码>my_form中不存在,例如:
Phoenix.HTML.Form.input_value(my_form, :non_exist)
例如,我可在“save”handle_event(
功能上添加以下代码:
my_form = socket.assigns.my_form
IO.inspect(my_form, label: "[ME]:form")
IO.inspect(Phoenix.HTML.Form.input_value(my_form, :input_int), label: "[ME]: input_value()" )
在我上报时,我在终端窗口看到以下产出:
[ME]:form: %Phoenix.HTML.Form{
source: %{"input_bool" => true, "input_int" => 3, "input_string" => ""},
impl: Phoenix.HTML.FormData.Map,
id: nil,
name: nil,
data: %{},
hidden: [],
params: %{"input_bool" => true, "input_int" => 3, "input_string" => ""},
errors: [],
options: [],
index: nil,
action: nil
}
[ME]: input_value(): 3
[ME]updated struct:: %MyApp.MyStruct{some_integer: "3", some_string: "", some_bool: ""}
[debug] Replied in 6ms
But, the value returned was the value which was used to create the form in mount()
.