从 handle_event 多次更新状态

huangapple go评论54阅读模式
英文:

Updating state multiple times from a handle_event

问题

有没有一种方法可以从 handle_event 调用中多次触发更新状态的重新渲染?

这是我尝试做的一些模糊想法:

def handle_event("button_clicked", %{button: which_button}, socket) do
  在完成工作之前发送一个回复(assign(socket, :working, true))
  BigLongTask.run(which_button)
  {:noreply, socket} # 这里的 working: false
end

这样,在我的 Heex 中,我可以切换一个旋转器:

<div :if={!@working}>
  <.button1 phx-click="clicked" phx-value-button="button1" />
  <.button2 phx-click="clicked" phx-value-button="button2" />
</div>

<.spinner :if={@working} />

我考虑使用 phx-click-loading CSS 来触发这个,但这仅限于当前被点击的按钮。在这里,我替换了按钮的父容器。

我还查看了 LiveView.send_update/3,这似乎正是我想要的,但它被设计用来发送消息给与 Live View 中某个组件关联的地方。将这两个按钮封装成一个专用组件当然是可能的,但对于我试图完成的任务来说似乎有些过于复杂。

谢谢。

英文:

Is there a way to trigger a re-render with an updated state multiple times from a handle_event call?

Here's some vague idea of what I'm trying to do:

def handle_event(&quot;button_clicked&quot;, %{button: which_button}, socket) do
  send_a_reply_before_finishing_your_work(assign(socket, :working, true))
  BigLongTask.run(which_button)
  {:noreply, socket} # working: false here
end

So that in my heex, I can toggle a spinner:

&lt;div :if={!@working}&gt;
  &lt;.button1 phx-click=&quot;clicked&quot; phx-value-button=&quot;button1&quot; /&gt;
  &lt;.button2 phx-click=&quot;clicked&quot; phx-value-button=&quot;button2&quot; /&gt;
&lt;/div&gt;

&lt;.spinner :if={@working} /&gt;

I looked at using phx-click-loading css to trigger this, but that's limited in scope to the current button being clicked. Here, I'm replacing a parent container of the button instead.

I also looked at LiveView.send_update/3, which seems like exactly what I'd want, but that's designed to send a message to a component attached somewhere within the Live View. Wrapping up the two buttons into a dedicated component certainly is possible but seems like overkill for what I'm trying to accomplish.

Thanks

答案1

得分: 2

看起来我与send_update/3函数非常接近,但实际解决方案是只使用Process.send/3

def handle_event("button_clicked", socket) do
  send(self(), :start_the_long_running_task_please)
  {:noreply, assign(socket, :working, true)}
end

def handle_info(:start_the_long_running_task_please, socket) do
  BigLongTask.run()
  {:noreply, assign(socket, :working, false)}
end
英文:

It seems like I was really close with send_update/3, but the actual solution was to just use Process.send/3:

def handle_event(&quot;button_clicked&quot;, socket) do
  send(self(), :start_the_long_running_task_please)
  {:noreply, assign(socket, :working, true)}
end

def handle_info(:start_the_long_running_task_please, socket) do
  BigLongTask.run()
  {:noreply, assign(socket, :working, false)}
end

huangapple
  • 本文由 发表于 2023年6月16日 01:17:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76484073.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定