javascript - Refreshing multiple partials with polling in Rails -
let's have list of statuses might this:
ul#list - @list_items.each |item| li.loading item #{item.id} - status: #{item.status} li item #{item.id} - status: #{item.status} li item #{item.id} - status: #{item.status} li.loading item #{item.id} - status: #{item.status}
which renders me:
item 1 - status: loading item 2 - status: finished item 3 - status: finished item 4 - status: loading
what periodically poll changes on individual list items , refresh them if status has changed. far able away refreshing whole list:
ul#list == render 'status_list', list_items: @list_items
coffee:
if $('.loading').length > 0 setinterval (=> @refreshlistpartial() ), 5000
where @refreshlitspartial
ajax function hits rails controller goes on refresh whole list partial:
$("#list").html("<%= escape_javascript(render partial: 'status_list', locals: { list_items: @list_items } ) %>");
but how 1 go in order check state of individual
list items on page , refresh them? know react easier solution task, possible accomplish rails without jumping on dozen hoops? thing came mind actioncable
(i'm using rails 5), opening perma-connection functionality seems overkill, i'd rather prefer polling.
update
just thinking out loud. refresh multiple partials instead of 1 i'll need arrive in .js.erb file:
<%- @items.each |item| %> $("#list-item-<%= item.id %>").html("<%= escape_javascript(render partial: 'item', locals: { list_item: item } ) %>"); <% end %>
the view should like:
ul#list @list_items.each |item| == render 'list_item', list_item: @list_item
so what's left ajax function should ids' of list items needed refreshed , send them controller array.
i ended doing extension of myself proposed in question update.
frontend code checks whether partials need refreshed based on data-tags:
class jobrequestpartialreload constructor: -> checkforrunningjobs = -> if $('.poll_for_changes').length > 0 @arr = [] $('.poll_for_changes').each (index, element) => @arr.push(element.closest('[data-id]').dataset.id) senddatatorails() senddatatorails = -> $.ajax url: "/jobs/refresh_list" method: "post" data: {jobrequestlist: @arr} setinterval (=> checkforrunningjobs() ), 10000 $(document).on 'turbolinks:load', new jobrequestpartialreload
controller:
def refresh_list ajax_data = params[:jobrequestlist].map(&:to_i) @job_requests = jobrequest.includes(...).where(id: ajax_data) respond_to |format| format.js end end
finally, js.erb file:
<% @job_requests.each |job| %> <% case job.state %> <% when 'initiated' %> // don't care <% when 'active' %> visiblestatus = $('#job-id-<%= job.id %> .status-list').text() if (visiblestatus == 'initiated') { $('#job-id-<%= job.id %>').html("<%= escape_javascript(render partial: 'job_requests/shared/job_request', locals: { job: job } ) %>"); <% else %> // failed, completed, etc. $('#job-id-<%= job.id %>').html("<%= escape_javascript(render partial: 'job_requests/shared/job_request', locals: { job: job } ) %>"); <% end %> <% end %>
answer update
i later added js code checked whether partials in actual user viewport, , checked them, @ rate of 5-10 seconds. reduced number of queries each client sending.
Comments
Post a Comment