从控制器动态更改视图 - Rails 中带有线程的进度条

发布于 2024-09-08 14:38:22 字数 606 浏览 9 评论 0原文

我的控制器中有一个耗时任务,我想在我的视图中触发一个简单的进度条/进度状态。

在我的控制器中,我有一些东西,比如

threads = []
total.times do |x|
    Thread.new {
        the_time_taking_task(x)
        #Something here to trigger the progressbar in the view
    }
end

threads.each { |aThread|  aThread.join }
render :action => 'some_action'    

我无法将渲染放在那里,因为它会引发双重渲染错误。 我尝试在那里放置渲染并返回,但出现“返回无法跨线程跳转”错误

我正在尝试渲染,因为这似乎是我的控制器可以与视图对话的唯一方式。我的方法是错误的吗?

想要在视图中使用像这样简单的东西,通过该调用应用进度条宽度,

<div style="width: <%= (percent_val)%>px; ">

请提出建议。

I have a time taking task in my controller for which I want to trigger a simple progress bar/progress status in my view.

In my controller I have something like

threads = []
total.times do |x|
    Thread.new {
        the_time_taking_task(x)
        #Something here to trigger the progressbar in the view
    }
end

threads.each { |aThread|  aThread.join }
render :action => 'some_action'    

I can't put a render in there because it throws a double render error.
I tried putting a render and return there and I got 'return can't jump across threads' error

I am trying render as it seems to be the only way my controller can talk to view. Is my approach wrong ?

Would want something simple like this in the view which applies the progress bar width through that call

<div style="width: <%= (percent_val)%>px; ">

Please advice.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

还不是爱你 2024-09-15 14:38:22

是的,这是一个错误的方法。

Web 是无状态的,您无法阻止渲染视图的进程并通过另一个请求获取它。

好方法是:

1)生成队列任务而不是线程。您可以使用delayed_job、resque 或队列系统,例如rabbitMQ 或beanstalkD

2) 添加控制器来检查队列中的进程是否结束以及进度如何。在里面,您输入队列 ID 并检查是否结束并返回进度百分比。

最简单的方法是通过 Ajax 来实现。

Yes it's a wrong approach.

The Web is stateless, and you can't block a process to render view and get it after by another request.

The good way is :

1) Generate a queue tasking instead of your thread. You can use delayed_job, resque or queue system, like rabbitMQ or beanstalkD

2) Add a controller to check if the process in your queue is end and how is progress. Inside, you put the queue id and check if is end or not and return the progress percent.

The easiest way is do that by Ajax.

小嗷兮 2024-09-15 14:38:22

是的,你的做法是错误的。

shingara 很好地解释了这一点。

我为您提供一个稍微具体的解决方案。

为了获得您想要的效果,您基本上需要以下步骤:

  1. 将线程卸载到后台作业服务器中。查看 resquedelayed_job
  2. 让后台作业将进度写入数据库或某些持久介质。
  3. 在 Rails 中,编写一个返回当前进度的操作(作为 json 或 xml)。
  4. 在您的视图中,编写一个定期的 ajax 请求,该请求调用步骤 3 中编写的操作
  5. 。相应地更新视图。

你完成了! :D

Yes, your approach is wrong.

shingara explains this well.

I'm offering a slightly more concrete solution for you.

To get the effect you want, you basically need the following steps:

  1. Offload the thread into a background job server. Checkout resque or delayed_job.
  2. Have the background job write the progress to database or some persistant medium.
  3. In Rails, write an action that returns the current progress (as json or xml)
  4. In your view, write a periodic ajax request that calls the action written in step 3.
  5. update the view accordingly.

You're done! :D

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文