Твиттер начальной загрузки 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');
});

Примечание: отрегулируйте селекторы по мере необходимости. Это самое общее.

Plunker

Или вы можете попытаться придумать более сложную схему, например, проверить, отличается ли ссылка, запускающая модал, от предыдущей. Если это так, уничтожь; если это не так, то нет необходимости перезагрузить.


1
@VladimirStarkov К сожалению об этом - кажется, я забыл hideкласс по модалу, поэтому, если ваше окно было слишком маленьким, модал мог блокировать события мыши на кнопках. По какой-то причине JSFiddle.net сегодня очень плох (получил 504 попытки обновить), поэтому я просто переделал пример на plnkr.co, который в любом случае лучше для AJAX.
Merv

3
есть еще одна проблема: в .modal-body по-прежнему будет содержаться текст, поэтому я добавил: <CODE> $ ('# myModal .modal-body'). text ("Loading ...") </ CODE> в скрытом событии слушатель
рбп

5
bs.modalу $(this).removeData('bs.modal')меня работал с Bootstrap 3
jvannistelrooy

2
Полный рабочий код для Boostrap 3$('body').on('hidden.bs.modal', '.modal', function () { $(this).removeData('bs.modal'); });
Кристоф Фондаччи

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. Это убьет любую ссылку и оставит вас пустым модал.
Банкзилла

Это не сработало для меня. Вот мой код, который работает: $ (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 вызывает функцию скрытия модального пространства, тем самым очищая мои переменные инициации.

Я обнаружил, что выполнение вызова removeData непосредственно перед тем, как код, запустивший модал, сработало. Так что мой код структурирован так ...

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

5

В Bootstrap 3.2.0 событие «on» должно быть в документе, и вы должны очистить модал:

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

В Bootstrap 3.1.0 событие on может быть на теле:

$('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 и вставлен в div .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('');
});

Это, безусловно, самый простой рабочий ответ, который я нашел. Ничего сложного в ответе, несколько строк кода и легко интерпретировать. Работал отлично с первого раза, возиться с ним.
Tarquin

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')
  })

(добавлен дополнительный интервал для ясности)

Это предотвращает любую нежелательную флэш-память старого модального содержимого, вызывая empty () для модального контейнера, а также удаляя данные.


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')будет достаточно и очень безопасно.
Джулиан Паоло Даяг

-4

Удачи с этим:

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

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