Rails - обновлять bootstrap поповерный контент с частичным после ajax - PullRequest
1 голос
/ 14 апреля 2020

Я создаю функцию уведомлений, используя bootstrap popover. Когда пользователь нажимает на уведомление, оно помечает это уведомление как прочитанное с помощью вызова ajax. В случае успеха * 1016 я хочу заменить содержимое поповера обновленной версией. Вот что у меня есть:

$(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 success.

Мой вопрос заключается в том, есть ли способ обойти это, что позволило бы мне динамически визуализировать партиал вместо его заполнения в js при загрузке страницы? Или, если нет, возможно, совершенно другой подход - я открыт для любых идей. Спасибо.

1 Ответ

1 голос
/ 15 апреля 2020

Вы можете получить частичное из вашего контроллера следующим образом:

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

Затем добавьте ответ в JS:

$('.notifications-list').append(resp)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...