Bootstrap 弹出窗口和 FullCalendar 的随机重复内容错误

Random duplicate content bug with Bootstrap popovers and FullCalendar

注意:我知道 bootstrap 中有一个错误导致 popovers/tooltips 调用 content function() 两次,但我认为这里不是这种情况.

我将 bootstrap 弹出窗口与 FullCalendar gem 结合使用来更新事件。

在弹出框内,有多个 div 获得 hidden/shown,具体取决于用户所在的视图(即,有一个用于显示事件信息的视图,另一个用于更新视图)。我处理这个问题的方法是使用 addClass('hide')removeClass('hide'),所以如果这不合适请纠正我。

当我点击一个事件时,它会显示弹出窗口,其中的内容被添加到一次(很好)。当我导航到弹出窗口内的更新 div 并发送 .ajax({type: 'PUT'}) 时,更新事件的弹出窗口显示两个内容 div(错误);然而,这种情况 随机发生

如果我重新加载整个 DOM 并一遍又一遍地重做该过程,这种重复发生的概率约为一半。

DOM 加载后单击弹出窗口时(好)

在调用 ajax PUT 后单击弹出窗口时,有时会发生这种情况(即使没有更改任何字段)

这是我发送 .ajax 请求的方式:

  // SAVE button for LESSONS, POPOVER ***/
  $('body').on('click', 'button.popover-lesson-save', function() {

    var title = $('.popover input.popover-lesson-title').val();
    var note = $('.popover input.popover-lesson-note').val();

    // Retrieve event data from popover
    var idStr = $('.popover div.popover-body').data('id');
    var id = parseInt(idStr);

    // Store event data into a hash for AJAX request and refetches events
    var data = {
      title: title,
      note: note
    };

    // Make PUT AJAX request to database
    $.ajax({
      url: '/lessons/' + id,
      type: 'PUT',
      data: data,
      dataType: 'json',

      success: function(resp){
        $('.popover div.popover-lessons-edit').addClass('hide');
        $('.popover div.popover-lessons-view').removeClass('hide');
        $('.popover').popover('hide');
        $('#calendar').fullCalendar( 'refetchEvents' );
      },
      error: function(resp){
        alert('Error code 2-502-1. Oops, something went wrong.');
      }

    });
  });

这是我在 FullCalendar 回调中所做的:

  // calendar options
  $('#calendar').fullCalendar({
    ..
    eventRender: function(calEvent, element, view){

        if (typeof $(element).data('bs.popover') === 'undefined'){
          // Find content html (append and clone prevents parent div from being overwritten)
          var content = $("<div />").append($('.popover-lessons-content').clone());
          var id = calEvent.id;

          // Attach popover to html element
          $(element).popover({
            container: 'body',
            placement: 'left',
            html: true,
            content: function(){
              return content.html(); // This randomly duplicates
            }
          });
        }
     }
  }

有些事告诉我这里

而不是 append()
var content = $("<div />").append($('.popover-lessons-content').clone());

你应该使用 appendTo()。但不确定 clone() 的目的所以我认为它应该看起来像:

var content = $("<div />").appendTo('.popover-lessons-content');

并且为了避免重复 $('.popover-lessons-content') 东西应该在附加到它之前被清除。

感谢@c-smile,我意识到错误在于我如何从我的视图文件中检索我的 html 模板:

var content = $("<div />").append($('.popover-lessons-content').clone());

相反,我应该这样做(经过大量修改后才有效):

      var content = $('.popover-lessons-content').html();

      $(element).popover({
        container: 'body',
        placement: 'left',
        html: true,
        content: function(){
          return content;
        }
      });

它采用直接的 html 而不是克隆 div 并弄得一团糟。