Biểu mẫu Phoenix LiveView không có bộ thay đổi

Để xử lý các thay đổi và gửi biểu mẫu, hãy sử dụng các sự kiện

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6 và
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
7. Nói chung, nên xử lý các thay đổi đầu vào ở cấp biểu mẫu, nơi tất cả các trường biểu mẫu được chuyển đến lệnh gọi lại của LiveView với bất kỳ thay đổi đầu vào nào. Ví dụ: để xử lý xác thực và lưu biểu mẫu theo thời gian thực, mẫu của bạn sẽ sử dụng cả hai liên kết
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
8 và
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
9

  
  
  

  
  
  

  

Lời nhắc nhở.

def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
0 là người trợ giúp của
def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
1. Đừng quên bao gồm
def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
2 ở đầu LiveView của bạn, nếu sử dụng người trợ giúp
def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
1. Ngoài ra, nếu sử dụng
def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
4, đừng quên
def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
5

Tiếp theo, LiveView của bạn chọn các sự kiện trong cuộc gọi lại

def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
6

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end

Cuộc gọi lại xác thực chỉ cần cập nhật bộ thay đổi dựa trên tất cả các giá trị đầu vào của biểu mẫu, sau đó gán bộ thay đổi mới cho ổ cắm. Nếu bộ thay đổi thay đổi, chẳng hạn như tạo lỗi mới, thì

def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
7 được gọi và biểu mẫu được hiển thị lại

Tương tự như vậy đối với các ràng buộc

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
7, cùng một cuộc gọi lại được gọi và sự kiên trì được cố gắng. Khi thành công, một bộ dữ liệu
def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
9 được trả về và ổ cắm được chú thích để chuyển hướng với
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
60 đến trang người dùng mới, nếu không, ổ cắm gán được cập nhật với bộ thay đổi bị lỗi để được kết xuất lại cho máy khách

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
61

Để cập nhật thẻ lỗi ở dạng thích hợp, thẻ lỗi phải chỉ định nó thuộc về đầu vào nào. Điều này được thực hiện với thuộc tính

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
61. Không thêm thuộc tính
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
61 sẽ dẫn đến hiển thị thông báo lỗi cho các trường biểu mẫu mà người dùng chưa thay đổi [e. g. các trường bắt buộc ở phía dưới trang]

Ví dụ:

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
64 của bạn có thể sử dụng chức năng này

def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end

Bây giờ, bất kỳ bộ chứa DOM nào có thuộc tính

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
61 sẽ nhận được một lớp
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
66 trong trường hợp các trường biểu mẫu chưa nhận đầu vào/tiêu điểm của người dùng. Các quy tắc css sau đây được tạo trong các dự án mới để ẩn lỗi

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6

đầu vào số

Đầu vào số là một trường hợp đặc biệt trong biểu mẫu LiveView. Trên các bản cập nhật có lập trình, một số trình duyệt sẽ xóa thông tin nhập không hợp lệ. Vì vậy, LiveView sẽ không gửi các sự kiện thay đổi từ ứng dụng khách khi đầu vào không hợp lệ, thay vào đó cho phép giao diện người dùng xác thực gốc của trình duyệt thúc đẩy tương tác của người dùng. Khi đầu vào trở nên hợp lệ, các sự kiện thay đổi và gửi sẽ được gửi bình thường

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
5

Điều này được biết là có rất nhiều vấn đề bao gồm khả năng truy cập, số lượng lớn được chuyển đổi thành ký hiệu hàm mũ và việc cuộn có thể vô tình làm tăng hoặc giảm số

Kể từ đầu năm 2020, những điều sau đây sẽ tránh được những cạm bẫy này và có thể sẽ phục vụ nhu cầu của ứng dụng của bạn và người dùng tốt hơn nhiều. theo https. // caniuse. com/#search=inputmode, phần sau đây được hỗ trợ bởi 90% thị trường di động toàn cầu với Firefox vẫn chưa triển khai

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
5

đầu vào mật khẩu

Đầu vào mật khẩu cũng được đặt biệt trong

def error_tag[form, field] do
  form.errors
  |> Keyword.get_values[field]
  |> Enum.map[fn error ->
    content_tag[:span, translate_error[error],
      class: "invalid-feedback",
      phx_feedback_for: input_id[form, field]
    ]
  end]
end
1. Vì lý do bảo mật, giá trị trường mật khẩu không được sử dụng lại khi hiển thị thẻ nhập mật khẩu. Điều này đòi hỏi phải thiết lập rõ ràng
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
68 trong đánh dấu của bạn, ví dụ

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
9

Gửi hành động biểu mẫu qua HTTP

Thuộc tính

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
69 có thể được thêm vào biểu mẫu để kích hoạt gửi biểu mẫu tiêu chuẩn trên bản vá lỗi DOM tới URL được chỉ định trong thuộc tính tiêu chuẩn
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
50 của biểu mẫu. Điều này hữu ích để thực hiện xác thực trước khi gửi biểu mẫu LiveView trước khi đăng lên tuyến bộ điều khiển cho các hoạt động yêu cầu đột biến phiên Plug. Ví dụ: trong mẫu LiveView của bạn, bạn có thể chú thích
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
69 bằng phép gán boolean

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
3

Sau đó, trong LiveView của bạn, bạn có thể chuyển đổi chỉ định để kích hoạt biểu mẫu với các trường hiện tại trong lần kết xuất tiếp theo

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
4

Khi

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
69 là đúng, LiveView sẽ ngắt kết nối rồi gửi biểu mẫu

Phục hồi sau sự cố hoặc ngắt kết nối

Theo mặc định, tất cả các biểu mẫu được đánh dấu bằng

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6 sẽ tự động khôi phục các giá trị đầu vào sau khi người dùng kết nối lại hoặc LiveView được kết nối lại sau sự cố. Điều này đạt được bằng cách máy khách kích hoạt cùng một
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6 cho máy chủ ngay sau khi quá trình gắn kết hoàn tất

Ghi chú. nếu bạn muốn phục hồi biểu mẫu hoạt động trong quá trình phát triển, vui lòng đảm bảo tắt tính năng tải lại trực tiếp trong quá trình phát triển bằng cách nhận xét trình cắm LiveReload trong tệp

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
55 của bạn hoặc bằng cách đặt
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
56 trong tệp
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
57 của bạn. Mặt khác, tải lại trực tiếp có thể khiến trang hiện tại được tải lại bất cứ khi nào bạn khởi động lại máy chủ, điều này sẽ loại bỏ tất cả trạng thái biểu mẫu

Đối với hầu hết các trường hợp sử dụng, đây là tất cả những gì bạn cần và quá trình khôi phục biểu mẫu sẽ diễn ra mà không cần xem xét. Trong một số trường hợp, khi các biểu mẫu được tạo từng bước theo kiểu có trạng thái, nó có thể yêu cầu xử lý khôi phục bổ sung trên máy chủ bên ngoài mã gọi lại

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6 hiện tại của bạn. Để kích hoạt khôi phục chuyên biệt, hãy cung cấp ràng buộc
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
59 trên biểu mẫu để chỉ định một sự kiện khác cần kích hoạt để khôi phục, sự kiện này sẽ nhận thông số biểu mẫu như bình thường. Ví dụ: hãy tưởng tượng một biểu mẫu trình hướng dẫn LiveView trong đó biểu mẫu có trạng thái và được xây dựng dựa trên bước người dùng đang thực hiện và theo các lựa chọn trước đó

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
5

Trên máy chủ, sự kiện

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
50 chỉ liên quan đến dữ liệu biểu mẫu máy khách hiện tại, nhưng máy chủ duy trì toàn bộ trạng thái của trình hướng dẫn. Để khôi phục trong trường hợp này, bạn có thể chỉ định một sự kiện khôi phục, chẳng hạn như
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
51 ở trên, sự kiện này sẽ kết nối với các cuộc gọi lại máy chủ sau trong LiveView của bạn

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
0

Để từ bỏ phục hồi biểu mẫu tự động, hãy đặt

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
52

Thông tin cụ thể về máy khách JavaScript

Ứng dụng khách JavaScript luôn là nguồn xác thực cho các giá trị đầu vào hiện tại. Đối với bất kỳ đầu vào cụ thể nào có tiêu điểm, LiveView sẽ không bao giờ ghi đè lên giá trị hiện tại của đầu vào, ngay cả khi giá trị đó khác với các bản cập nhật được kết xuất của máy chủ. Điều này hoạt động tốt cho các bản cập nhật mà các tác dụng phụ lớn không được mong đợi, chẳng hạn như lỗi xác thực biểu mẫu hoặc UX bổ sung xung quanh các giá trị đầu vào của người dùng khi họ điền vào biểu mẫu

Đối với các trường hợp sử dụng này, đầu vào

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6 không liên quan đến việc tắt chỉnh sửa đầu vào trong khi một sự kiện đến máy chủ đang diễn ra. Khi một sự kiện
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
6 được gửi đến máy chủ, thẻ đầu vào và thẻ biểu mẫu gốc sẽ nhận được lớp css
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
55, sau đó tải trọng được đẩy đến máy chủ với thông số
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
56 trong tải trọng gốc chứa không gian khóa của tên đầu vào đã kích hoạt thay đổi

Ví dụ: nếu đầu vào sau kích hoạt sự kiện thay đổi

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
5

Máy chủ

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
57 sẽ nhận được tải trọng

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
2

Sự kiện

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
7 được sử dụng để gửi biểu mẫu khi các tác dụng phụ chính thường xảy ra, chẳng hạn như hiển thị vùng chứa mới, gọi dịch vụ bên ngoài hoặc chuyển hướng đến một trang mới

Khi gửi biểu mẫu bị ràng buộc với sự kiện

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
7

  1. Đầu vào của biểu mẫu được đặt thành
    def render[assigns] ...
    
    def mount[_params, _session, socket] do
      {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
    end
    
    def handle_event["validate", %{"user" => params}, socket] do
      changeset =
        %User{}
        |> Accounts.change_user[params]
        |> Map.put[:action, :insert]
    
      {:noreply, assign[socket, changeset: changeset]}
    end
    
    def handle_event["save", %{"user" => user_params}, socket] do
      case Accounts.create_user[user_params] do
        {:ok, user} ->
          {:noreply,
           socket
           |> put_flash[:info, "user created"]
           |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}
    
        {:error, %Ecto.Changeset{} = changeset} ->
          {:noreply, assign[socket, changeset: changeset]}
      end
    end
    90
  2. Bất kỳ nút gửi nào trên biểu mẫu đều bị tắt
  3. Biểu mẫu nhận lớp
    def render[assigns] ...
    
    def mount[_params, _session, socket] do
      {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
    end
    
    def handle_event["validate", %{"user" => params}, socket] do
      changeset =
        %User{}
        |> Accounts.change_user[params]
        |> Map.put[:action, :insert]
    
      {:noreply, assign[socket, changeset: changeset]}
    end
    
    def handle_event["save", %{"user" => user_params}, socket] do
      case Accounts.create_user[user_params] do
        {:ok, user} ->
          {:noreply,
           socket
           |> put_flash[:info, "user created"]
           |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}
    
        {:error, %Ecto.Changeset{} = changeset} ->
          {:noreply, assign[socket, changeset: changeset]}
      end
    end
    91

Khi hoàn thành xử lý máy chủ của sự kiện

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
7

  1. Biểu mẫu đã gửi được kích hoạt lại và mất lớp
    def render[assigns] ...
    
    def mount[_params, _session, socket] do
      {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
    end
    
    def handle_event["validate", %{"user" => params}, socket] do
      changeset =
        %User{}
        |> Accounts.change_user[params]
        |> Map.put[:action, :insert]
    
      {:noreply, assign[socket, changeset: changeset]}
    end
    
    def handle_event["save", %{"user" => user_params}, socket] do
      case Accounts.create_user[user_params] do
        {:ok, user} ->
          {:noreply,
           socket
           |> put_flash[:info, "user created"]
           |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}
    
        {:error, %Ecto.Changeset{} = changeset} ->
          {:noreply, assign[socket, changeset: changeset]}
      end
    end
    91
  2. Đầu vào cuối cùng có tiêu điểm được khôi phục [trừ khi đầu vào khác đã nhận được tiêu điểm]
  3. Các bản cập nhật được vá vào DOM như bình thường

Để xử lý các sự kiện tiềm ẩn, bất kỳ thẻ HTML nào cũng có thể được chú thích bằng

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
94, thẻ này hoán đổi
def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
95 của phần tử với giá trị được cung cấp trong quá trình gửi sự kiện. Ví dụ: đoạn mã sau sẽ thay đổi nút "Lưu" thành "Đang lưu. " và khôi phục nó thành "Save" khi xác nhận

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
3

Bạn cũng có thể tận dụng các lớp trạng thái tải CSS của LiveView để hoán đổi nội dung biểu mẫu của bạn trong khi biểu mẫu đang gửi. Ví dụ: với các quy tắc sau trong

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
96 của bạn

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
4

Bạn có thể hiển thị và ẩn nội dung bằng đánh dấu sau

def render[assigns] ...

def mount[_params, _session, socket] do
  {:ok, assign[socket, %{changeset: Accounts.change_user[%User{}]}]}
end

def handle_event["validate", %{"user" => params}, socket] do
  changeset =
    %User{}
    |> Accounts.change_user[params]
    |> Map.put[:action, :insert]

  {:noreply, assign[socket, changeset: changeset]}
end

def handle_event["save", %{"user" => user_params}, socket] do
  case Accounts.create_user[user_params] do
    {:ok, user} ->
      {:noreply,
       socket
       |> put_flash[:info, "user created"]
       |> redirect[to: Routes.user_path[MyAppWeb.Endpoint, MyAppWeb.User.ShowView, user]]}

    {:error, %Ecto.Changeset{} = changeset} ->
      {:noreply, assign[socket, changeset: changeset]}
  end
end
5

Ngoài ra, chúng tôi thực sự khuyên bạn nên bao gồm thuộc tính "id" HTML duy nhất trên biểu mẫu. Khi anh chị em DOM thay đổi, các thành phần không có ID sẽ được thay thế thay vì di chuyển, điều này có thể gây ra sự cố chẳng hạn như trường biểu mẫu bị mất tiêu điểm

Chủ Đề