英文:
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("button_clicked", %{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:
<div :if={!@working}>
<.button1 phx-click="clicked" phx-value-button="button1" />
<.button2 phx-click="clicked" phx-value-button="button2" />
</div>
<.spinner :if={@working} />
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("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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论