1

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

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

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

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

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

4

2 回答 2

2

我认为当您收到广播消息时,最好使用 ActionCable 并使用 ajax 使用 js.erb 呈现部分内容。即在您的/assets/javascript/channels/comments.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
    });
  }
});

在您的评论控制器中,您可以使用您收到的数据在 /comments/update_comments 方法中执行您需要的任何操作,这样它会影响您呈现的部分。可以说它只会刷新@comments。然后在你的视图文件中使用这个 update_comments.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 %>

希望我自己解释。

于 2017-07-20T17:51:34.303 回答
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);
  },
于 2018-02-14T15:03:56.620 回答