Набор изменений не обновляется при обновлении выпадающих данных

#elixir #phoenix-framework #liveview

#elixir #phoenix-framework #просмотр в реальном времени

Вопрос:

Предположим, у меня есть данные:

 data = [[key: 1, value: "1"], [key: 2, value: "2"] ,[key: 3, value: "3"]]
child_data = %{1: [key: 1, value: "exists"]}
  

И html:

 <%= select f, :corporation_id, data %>
<%= select f, :company_id, child_data[Ecto.changeset.get_field(@changeset, :corporation_id)] %>
  

Моя схема и набор изменений выглядят следующим образом:

 embedded_schema do
    field :corporation_id, :integer
    field :company_id, :integer
  end

def changeset(selected_org, attrs) do
    selected_org
    |> cast(attrs, [:corporation_id, :company_id])
    |> validate_required([:corporation_id, :company_id])
  end
  

Проблема заключается в следующем: когда я изменяю данные company набора изменений, они не обновляются, старый идентификатор остается, и он по-прежнему является действительным набором изменений. Насколько я понимаю, это происходит потому, что при обновлении данных событие проверки не генерируется.

Есть ли обходной путь для этой проблемы?

Ответ №1:

К сожалению, вы не сможете выполнить то, что хотите, без JavaScript или нового LiveView от Phoenix. Поскольку ваш шаблон отправляется в браузер, единственный способ справиться с реактивностью — использовать JavaScript. В вашем случае вам нужно отправить все дочерние данные в select: <%= select f, :company_id, child_data %> . Затем, используя JavaScript, вы прослушиваете change событие в поле корпорации, чтобы отфильтровать значения child_data

Комментарии:

1. Я уже использую liveview, пожалуйста, обратите внимание на теги

Ответ №2:

Хорошо, похоже, что в настоящее время это ограничение LiveView. Используя перехват обновления в JS, я смог отправить обновление на сервер. Перехват:

 Hooks.WorkaroundHook = {
  updated() {
    this.pushEvent("workaround", this.el.selectedIndex)
  }
}
  

И дескриптор:

   def handle_event("workaround", index, socket) do
    # if changeset is valid and index is 0 add error to changeset
    {:noreply, socket}
  end