【问题标题】:Rendering HTML from a job onto a page in Rails 5在 Rails 5 中将作业中的 HTML 渲染到页面上
【发布时间】:2016-01-15 16:30:40
【问题描述】:

我希望创建一个在从后端数据库收集选定资源后异步呈现部分的作业。我这样做是因为我获取的数据需要很长时间才能获取,并且我希望能够在收到数据后显示这些数据。现在我的代码看起来像这样:

class CommentsJob < ApplicationJob
  queue_as: default
  def perform(commenter_company)
   @comments = Comment.where(company: commenter_company)
   @html = CommentsController.render partial: "comments", assigns {comments: @comments }
  end
end

我已经设置了 _cmets.html.erb 部分。我还将队列适配器设置为异步,因此该作业确实在后台运行并在页面加载后完成。

我成功地获取了 html 并将其设置为作业中的 @html 实例变量。

我的问题是:我怎样才能将这个@html 内容放到已经呈现的页面上?这可以在工作中完成,还是我需要使用 ActionCable/websockets 来做到这一点?提前致谢!

【问题讨论】:

  • 这似乎是你应该使用 javascript 的东西。我很肯定会展示你需要硬刷新或某种类型的 JS 的部分内容。
  • 你必须实现一些缓存。您正在尝试做的是预热缓存。查看使用滑轨缓存俄罗斯娃娃
  • 谢谢大家。一旦数据在 ruby​​ 中可用,我宁愿不必进行刷新和显示数据,但我知道无法按照我设置的方式推送到客户端。另外,如果不刷新页面,使用缓存是否不起作用?
  • 我在几周前实现了这个。只需使用 ActionCable 将数据推送回客户端即可。

标签: ruby-on-rails websocket rails-activejob ruby-on-rails-5 actioncable


【解决方案1】:

我认为当您收到广播消息时,最好使用 ActionCable 并使用 ajax 以 js.erb 呈现部分。即在您的 /assets/javascript/channels/cmets.js 中:

this.App = {};

App.cable = ActionCable.createConsumer();

App.comments = App.cable.subscriptions.create('CommentsChannel', {
  received: function(data) {
    this.renderComments(data);
  },

  renderComments: function(data) {
    $.ajax({
      url: "/comments/update_comments"
      data: { data: data } // Depending on how you structure the data you received
    });
  }
});

在您的 cmets 控制器中,您可以在 /cmets/update_cmets 方法中使用您收到的数据执行您需要的任何操作,这样它会影响您渲染的部分。可以说它只会刷新@cmets。然后在你的视图文件中使用这个 update_cmets.js.erb,它会在给定的 html 元素中刷新你的部分:

//app/views/comments/update_comments.js.erb
$('#comments_container').html("<%= escape_javascript(render partial: 'comments') %>");

你的部分可能是这样的:

<!-- app/views/comments/_comments.html.erb -->
<% @comments.each do |comment| %>
  <p><%= comment.user %>: <%= @comment.message %></p>
<% end %>

希望我自己解释一下。

【讨论】:

    【解决方案2】:

    你可以这样做

    ActionCable.server.broadcast(
      "comments_#{@comment.id}_channel",
      view: ApplicationController.render(
        partial: 'comments/commment',
        locals: { comment: @comment }
      )
    )
    

    在js中

    App.comments = App.cable.subscriptions.create(
      {channel: 'CommentsChannel', id: comment_id }, {
      received: function(data) {
         $('#comments').append(data.view);
      },
    

    【讨论】:

      猜你喜欢
      • 2019-12-20
      • 1970-01-01
      • 2016-10-14
      • 2015-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多