简体   繁体   English

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

[英]Change view dynamically from controller - Progress bar with threading in Rails

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 我尝试将渲染器放回原处,但出现“ return can't jump across threads ”错误

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. 请指教。

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. Web是无状态的,您不能阻止进程渲染视图并在另一个请求之后获取它。

The good way is : 好的方法是:

1) Generate a queue tasking instead of your thread. 1)生成队列任务而不是线程。 You can use delayed_job, resque or queue system, like rabbitMQ or beanstalkD 您可以使用delay_job,resque或队列系统,例如RabbitMQ或beanstalkD

2) Add a controller to check if the process in your queue is end and how is progress. 2)添加一个控制器,以检查队列中的进程是否结束以及进度如何。 Inside, you put the queue id and check if is end or not and return the progress percent. 在内部,您放入队列ID并检查是否结束,然后返回进度百分比。

The easiest way is do that by Ajax. 最简单的方法是由Ajax完成。

Yes, your approach is wrong. 是的,您的方法是错误的。

shingara explains this well. shingara很好地解释了这一点。

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 . 结帐resquedelay_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) 在Rails中,编写一个返回当前进度的操作(以json或xml格式)
  4. In your view, write a periodic ajax request that calls the action written in step 3. 在您看来,编写一个周期性的ajax请求,以调用在步骤3中编写的操作。
  5. update the view accordingly. 相应地更新视图。

You're done! 你完成了! :D :D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM