У віддаленому режимі завантажувального пристрою Twitter кожен раз відображається однаковий вміст


263

Я використовую завантажувальний засіб Twitter, я вказав режим

<div class="modal hide" id="modal-item">

    <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal">x</button>
        <h3>Update Item</h3>
    </div>

    <form action="http://www.website.com/update" method="POST" class="form-horizontal">

    <div class="modal-body">
        Loading content...
    </div>

    <div class="modal-footer">
        <a href="#" class="btn" data-dismiss="modal">Close</a>
        <button class="btn btn-primary" type="submit">Update Item</button>
    </div>

    </form>

</div>

І посилання

<a href="http://www.website.com/item/1" data-target="#modal-item" data-toggle="modal">Edit 1</a>
<a href="http://www.website.com/item/2" data-target="#modal-item" data-toggle="modal">Edit 2</a>
<a href="http://www.website.com/item/3" data-target="#modal-item" data-toggle="modal">Edit 2</a>

Коли я натискаю будь-яке з цих посилань вперше, я бачу правильний вміст, але коли я натискаю на інші посилання, він показує той самий вміст, завантажений вперше, він не оновлює вміст.

Я хочу, щоб вона оновлювалася щоразу, коли її клацали.

PS: Я можу з легкістю змусити його працювати за допомогою спеціальної функції jQuery, але я хочу знати, чи можливо це за допомогою нативного дистанційного функції Bootstrap, оскільки це повинно бути досить просто, і я думаю, що я просто ускладнюю справи.


Те саме виправлення, але змінено для Bootstrap 3. Bootstrap 3 представляє простори імен. plnkr.co/edit/HWSgSw?p=preview
Джефф Х

5
Зауважте, що remoteМодалі застаріли, як у Bootstrap v3.2.1, і вони будуть відсутній у v4.
cvrebert

Відповіді:


447

Проблема двояка.

По-перше , як тільки модальний об'єкт інстанціюється, він наполегливо приєднується до елемента, визначеного data-targetнаступними викликами, і показує, що модальний режим буде викликати лише toggle()його, але не оновлюватиме значення у options. Отже, навіть якщо hrefатрибути відрізняються від ваших різних посилань, коли модуль переключений, значення для значення remoteне оновлюється. У більшості варіантів можна обійти це шляхом прямого редагування об'єкта. Наприклад:

$('#myModal').data('bs.modal').options.remote = "http://website.com/item/7";

Однак це не спрацює в цьому випадку, тому що ...

По-друге , плагін Modal призначений для завантаження віддаленого ресурсу в конструктор об'єкта Modal, що, на жаль, означає, що навіть якщо зміни будуть внесені до options.remote, він ніколи не буде перезавантажений .

Простий засіб - знищити Модальний об'єкт перед наступними перемиканнями. Один із варіантів - просто знищити його після того, як він закінчить приховувати:

$('body').on('hidden.bs.modal', '.modal', function () {
  $(this).removeData('bs.modal');
});

Примітка: За необхідності відрегулюйте селектори. Це найбільш загальне.

Плункер

Або ви можете спробувати створити більш складну схему, щоб зробити щось на кшталт перевірки, чи посилання, що запускає модаль, відрізняється від попереднього. Якщо є, знищити; якщо це не так, то не потрібно перезавантажувати.


1
@VladimirStarkov Вибачте за це - здається, я забув hideклас на модалі, тому, якщо ваше вікно було занадто мало, модаль, можливо, блокував події миші на кнопках. Чомусь JSFiddle.net дійсно поганий сьогодні вранці (отримав 504, що намагається оновити), тож я просто переробив приклад на plnkr.co, що краще для AJAX у будь-якому випадку.
merv

3
є ще одна проблема: .modal-body все ще буде містити текст у ньому, тому я додав: <CODE> $ ('# myModal .modal-body'). текст ("Завантаження ...") </CODE> у слухача прихованих подій
rbp

5
bs.modalв $(this).removeData('bs.modal')працював для мене з Bootstrap 3
jvannistelrooy

2
Повний робочий код для Boostrap 3$('body').on('hidden.bs.modal', '.modal', function () { $(this).removeData('bs.modal'); });
Christophe Fondacci

1
Я також би перевірив, чи модальний var modalData = $(this).data('bs.modal'); if (modalData && modalData.options.remote)...
пристрій

171

Для завантажувального пристрою 3 слід використовувати:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});

17
Мій герой. Любіть ці незадокументовані зміни.
Жорін

2
Це дуже допомогло. Bootstrap 3 не є сумісним назад, і більшість контенту на SO (або інших форумах) стосується BS <3, спроба цих рішень марно витрачає багато часу.
Swapnil

7
Не ідеально: вона коротко показує старий вміст перед новим вмістом.
Лоран

3
Якщо ви хочете спорожнити модаль за допомогою наведеного вище прикладу, ви повинні мати змогу додати наступне перед або після remoteDataрядка:$(this).empty()
jgillman

11
Не слід використовувати $(this).empty(). remoteОпція завантажує видалені дані в гніздовий <div class="modal-content">елемент. Використовуйте $('.modal-content', this).empty();замість цього.
Гевін

50

Для Bootstrap 3.1 вам потрібно буде видалити дані та видалити, modal-contentа не все діалогове вікно (3.0), щоб уникнути мерехтіння під час очікування завантаження віддаленого вмісту.

$(document).on("hidden.bs.modal", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});

Якщо ви використовуєте невіддалені модалі, то наведений вище код, звичайно, видалить їх вміст після закриття (погано). Вам може знадобитися додати щось до цих модалів (наприклад, .local-modalклас), щоб вони не впливали. Потім змініть наведений вище код на:

$(document).on("hidden.bs.modal", ".modal:not(.local-modal)", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});

На віддалених сторінках переконайтеся, що ви не завантажуєте завантажувальний файл або бібліотеки jquery. Це вб'є будь-яку посилання і залишить вас з порожнім порожнім модалом.
Bankzilla

Це не працювало для мене. Ось мій код, який працює: $ (document) .on ("hidden.bs.modal", ".modal", function (e) {if (! $ (E.target) .is (". Local-modal ")) {$ (e.target) .removeData (" bs.modal "). find (". modal-content "). empty ();}});
Кевін

Коли я використовую $(e.target).removeData("bs.modal").find(".modal-content").empty();це так, ніби мій модал якось приховується, і з’являється лише сіра накладка.
Аксель

30

Дякую мерв. Я почав роздумувати над boostrap.js, але ваша відповідь - це швидкий і чистий шлях. Ось що я в кінцевому підсумку використав у своєму коді.

$('#modal-item').on('hidden', function() {
    $(this).removeData('modal');
});

21

Прийнята відповідь не працювала для мене, тому я пішов із JavaScript, щоб це зробити.

<a href="/foo" class="modal-link">
<a href="/bar" class="modal-link">

<script>
$(function() {
    $(".modal-link").click(function(event) {
        event.preventDefault()
        $('#myModal').removeData("modal")
        $('#myModal').modal({remote: $(this).attr("href")})
    })
})

14

Це працює з Bootstrap 3 FYI

$('#myModal').on('hidden.bs.modal', function () {
  $(this).removeData('bs.modal');
});

7

Мій проект побудований у Yii та використовує плагін Bootstrap-Yii, тому ця відповідь актуальна лише у тому випадку, коли ви використовуєте Yii.

Наведене вище виправлення спрацювало, але лише після першого модального показу. Перший раз він вийшов порожнім. Я думаю, що це тому, що після мого ініціювання коду Yii викликає функцію приховання модалу, тим самим очищаючи мої ініціальні змінні.

Я виявив, що поставити виклик deleteData безпосередньо перед кодом, який запустив модаль, зробив свою справу. Тож мій код структурований так ...

$ ("#myModal").removeData ('modal');
$ ('#myModal').modal ({remote : 'path_to_remote'});

5

У Bootstrap 3.2.0 подія "увімкнено" має бути в документі, і ви повинні спорожнити модал:

$(document).on("hidden.bs.modal", function (e) {
    $(e.target).removeData("bs.modal").find(".modal-content").empty();
});

У Bootstrap 3.1.0 подія "увімкнено" може бути на тілі:

$('body').on('hidden.bs.modal', '.modal', function () {
    $(this).removeData('bs.modal');
});

Рішення 3.2 було єдиним, що працювало для мене належним чином у Bootstrap 3.1 - використовуючи підхід до тіла, деякі мої події в режимі модалі неприховані.
StuartQ

3

Чому б не зробити це більш загальним з BS 3? Просто використовуйте "[щось] модальне" як ідентифікатор модального DIV.

$("div[id$='modal']").on('hidden.bs.modal',
    function () {
        $(this).removeData('bs.modal');
    }
);

2

Єдиний робочий варіант для мене:

$('body').on('hidden.bs.modal', '#modalBox', function () {
    $(this).remove();
});

Я використовую Bootstrap 3 і у мене є функція, popup('popup content') яка називається, що додає модальне поле html.


2
це єдине, що працювало для мене з BS 3.3.6. також використовуючи шаблон ручки. Я пропоную використовувати документ замість тіла.
dbinott

1

Додавання $ (this) .html (''); щоб також очистити видимі дані, і це працює чудово


1

Якщо надана віддалена URL-адреса, вміст буде завантажено один раз за допомогою методу завантаження jQuery та введено у розділ .modal-content. Якщо ви використовуєте data-api, ви можете альтернативно використовувати атрибут href для визначення віддаленого джерела. Приклад цього наведено нижче

$.ajaxSetup ({
    // Disable caching of AJAX responses
    cache: false
});

1

Я додав щось подібне, тому що старіший вміст відображається до появи нового, з .html ('') всередині .modal-content очистить HTML всередині, сподіваюся, що це допоможе

$('#myModal').on('hidden.bs.modal', function () {
   $('#myModal').removeData('bs.modal');
   $('#myModal').find('.modal-content').html('');
});

Це, безумовно, найпростіша відповідь, яку я знайшов. Нічого складного у відповіді, кілька рядків коду та їх легко інтерпретувати. Працював ідеально перший раз, коли возився з ним.
Таркін

0

Я написав простий фрагмент, який обробляє оновлення модаля. В основному він зберігає натиснуте посилання в даних модалу і перевіряє, чи це та сама посилання, яку було натиснуто, видаляючи модальні дані чи ні.

var handleModal = function()
{
    $('.triggeringLink').click(function(event) {
        var $logsModal = $('#logsModal');
        var $triggeringLink = $logsModal.data('triggeringLink');

        event.preventDefault();

        if ($logsModal.data('modal') != undefined
            && $triggeringLink != undefined
            && !$triggeringLink.is($(this))
        ) {
            $logsModal.removeData('modal');
        }

        $logsModal.data('triggeringLink', $(this));

        $logsModal.modal({ remote: $(this).attr('href') });
        $logsModal.modal('show');
    });
};

0

Для Bootstrap 3 в modal.js я змінив:

$(document)
  .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
  .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open'); })

до

$(document)
  .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })
  .on('hidden.bs.modal', '.modal', function () { 
    $(this).removeData('bs.modal').empty()
    $(document.body).removeClass('modal-open')
  })

(для наочності додано додатковий інтервал)

Це запобігає будь-якому небажаному спалаху старого модального вмісту, викликаючи порожній () на модальному контейнері, а також видаляючи дані.


0
        $('#myModal').on('hidden.bs.modal', function () {
            $(this).removeData('modal');
        });

Цей працює для мене.


0

Цей інший підхід для мене добре працює:

$("#myModal").on("show.bs.modal", function(e) {
    var link = $(e.relatedTarget);
    $(this).find(".modal-body").load(link.attr("href"));
});

0
$('body').on('hidden.bs.modal', '.modal', function () {
       $("#mention Id here what you showed inside modal body").empty()
});

Який html-елемент ви хочете спорожнити (div, span тощо).


0

Цей для мене працює:

модальний

<div class="modal fade" id="searchKaryawan" tabindex="-1" role="dialog" aria-labelledby="SearchKaryawanLabel" aria-hidden="true"> <div class="modal-dialog">
<div class="modal-content">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
    <h4 class="modal-title" id="SearchKaryawanLabel">Cari Karyawan</h4>
  </div>
  <div class="modal-body">
    <input type="hidden" name="location">
    <input name="cariNama" type="text" class="form-control" onkeyup="if (this.value.length > 3) cariNikNama();" />
    <div class="links-area" id="links-area"></div>
  </div>
  <div class="modal-footer">
  </div>
</div> </div></div>

сценарій

<script type="text/javascript">$('body').on('hidden.bs.modal', '.modal', function () {  $(".links-area").empty() }); </script>

область посилань - це область, куди я ввожу дані і потрібно очистити


0

Розширена версія прийнятої відповіді від @merv. Він також перевіряє, чи прихований модальний модуль завантажений із віддаленого джерела та очищає старий вміст, щоб запобігти його спалаху.

$(document).on('hidden.bs.modal', '.modal', function () {
  var modalData = $(this).data('bs.modal');

  // Destroy modal if has remote source – don't want to destroy modals with static content.
  if (modalData && modalData.options.remote) {
    // Destroy component. Next time new component is created and loads fresh content
    $(this).removeData('bs.modal');
    // Also clear loaded content, otherwise it would flash before new one is loaded.
    $(this).find(".modal-content").empty();
  }
});

https://gist.github.com/WojtekKruszewski/ae86d7fb59879715ae1e6dd623f743c5


-1

Тестовано на Bootstrap версії 3.3.2

  $('#myModal').on('hide.bs.modal', function() {
    $(this).removeData();
  });

1
Це жахливе рішення. Виклик .removeData()без параметрів дозволить jquery видалити всі дані, приєднані до цього елемента. Що стосується проблеми Ора в те, .removeData('bs.modal')чи .removeData('modal')буде достатньо і дуже безпечно.
Julian Paolo Dayag

-4

Удачі з цим:

$('#myModal').on('hidden.bs.modal', function () {
    location.reload();
});

2
це марно. перезавантаження сторінки не є рішенням.
dbinott
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.