Rails - 在ajax之后使用部分更新引导弹出内容

Posted

技术标签:

【中文标题】Rails - 在ajax之后使用部分更新引导弹出内容【英文标题】:Rails - update bootstrap popover content with partial after ajax 【发布时间】:2020-07-27 05:44:41 【问题描述】:

我正在使用引导弹出框构建通知功能。当用户单击通知时,它将通过 ajax 调用将该通知标记为已读。在 ajax 成功时,我想用更新的版本替换弹出框的内容。这是我目前所拥有的:

$(document).ready(function()
  $("#notificationsBell").popover(
    'title' : $('.notifications-title-header').html(),
    'html' : true,
    'placement' : 'left',
    'content' : $(".notifications-list").html()
  ); 
);

$('#notificationsBell').off("click").on("click", function() 
  $("#notificationsBell").popover('toggle');
)

$(document).on("click", ".notif-popup-container", function() 
  // 1. get correct id for clicked notification
  var notifId = $(this).attr("id");

  // 2. Update the notification to be read and show update
  $.post(
    "/notifications/read",
     notif_id: notifId ,
  ).done(function(data) 
    $('#notifUnreadCount').html(data.unread_notifs);
    
  // 3. Replace html content of hidden div with updated notifications
  $('.notifications-list').html("<%= j (render partial: 'notifications/partials/test_partial') %>");
    
  // 4. Set popover content to be that div's html
  var popover = $('#notificationsBell').data('bs.popover');
  popover.config.content = $('.notifications-list').html();
)
# what is originally stored in the popover 

<div style="display:none" class="notifications-list">
  <%= render 'notifications/partials/popover_notifications' %>
</div>

# _popover_notifications.html.erb
# this is rendered twice, once above and once on ajax success

<% unread_notifications = Notification.unread_count(current_user) %>
<% if unread_notifications.eql? 0 %>
    No notifications to display! You are up to date.
<% else %>
    <% notifs = current_user.notifications.where(read_at: nil).order("created_at DESC") %>
    <% notifs.each do |notif| %>
        <div class="media n-media notif-popup-container notif-display" id=<%= notif.id %> >
          <b><p><%= notif.notify_type %></p></b>
          <span class="n-date trans-timestamp dateTime" data-momentiz="(<%= notif.momentize %>)"></span>
          <p><%= notif.message %></p>
        </div>
    <% end %>
<% end %>

此内容通过部分显示。然而,这就是问题出现的地方。虽然我希望在 ajax 成功时渲染 ajax 成功回调中的部分,但它最近了解到部分的渲染首先由服务器完成(甚至在任何 js 运行之前),然后是结果被传递回 javascript

如此有效,两个部分都在页面加载时呈现,这意味着我不能再在 ajax 成功后通过部分呈现动态地动态设置弹出框内容。

我的问题是,有没有一种方法可以让我动态呈现部分内容,而不是在页面加载时将其填充到 js 中?或者如果不是,可能是一种完全不同的方法——我对任何想法都持开放态度。谢谢。

【问题讨论】:

你可以通过 JS .append() 它,一旦你从服务器取回数据,在部分中构造相同的 HTML 并将对象的数据附加到 html 然后将其附加到 @ 987654324@ 嗨@ricks,你的意思是不是渲染部分,而是将部分中的代码复制到 append() 函数?看起来代码会这样重复。 抱歉,刚刚发布的答案应该可以满足您的需求,您需要使用控制器获取部分内容,以便您可以附加 HTML 你在使用turbolinks吗? 是的,我正在使用 turbolinks 【参考方案1】:

您可以像这样从控制器中获取部分内容:

class TestController < ApplicationController
  def render_partial

    notification_id = params[:notification_id]

    # Fetch notification data
    notification = Notification.find(notification_id)

    # Return partial with new notification data
    render partial: 'notifications/partials/test_partial', locals: :notification => notification
  end
end

然后appendJS中的响应:

$('.notifications-list').append(resp)

【讨论】:

你才是真正的男人!对新定义的控制器方法使用另一个 ajax 调用,类似于您上面描述的方法。

以上是关于Rails - 在ajax之后使用部分更新引导弹出内容的主要内容,如果未能解决你的问题,请参考以下文章

rails 4 bootstrap 3 ajax模式

键输入在引导弹出窗口输入中不起作用 - jquery

引导弹出窗口未显示在所有元素之上

用于桌面和移动平台的 Twitter 引导弹出框触发器

我如何防止在 angularJs 中显示引导弹出窗口

容器移动时的引导弹出位置