Twitter bootstrap modal ระยะไกลจะแสดงเนื้อหาเดียวกันทุกครั้ง


263

ฉันใช้ bootstrap ของ 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 modal เพราะมันควรจะง่ายพอและฉันคิดว่าฉันเป็นเพียงแค่สิ่งที่ซับซ้อน


Same Fix แต่แก้ไขสำหรับ Bootstrap 3 Bootstrap 3 แนะนำเนมสเปซ plnkr.co/edit/HWSgSw?p=preview
Jeff H

5
โปรดทราบว่าremoteModals นั้นเลิกใช้แล้วใน Bootstrap v3.2.1และจะหายไปใน v4
cvrebert

คำตอบ:


447

ปัญหาคือสองเท่า

ครั้งแรกเมื่อวัตถุ Modal ถูกสร้างมันเป็นที่แนบมาเสมอกับองค์ประกอบที่ระบุโดยdata-targetและโทรตามมาเพื่อแสดงให้เห็นว่าคำกริยาจะเรียกtoggle()มัน optionsแต่จะไม่ปรับปรุงค่าในที่ ดังนั้นแม้ว่าhrefแอตทริบิวต์จะมีความแตกต่างกันในลิงค์ที่แตกต่างกันของคุณเมื่อ modal ถูกสลับค่าสำหรับการremoteไม่ได้รับการปรับปรุง สำหรับตัวเลือกส่วนใหญ่คุณสามารถแก้ไขได้โดยแก้ไขวัตถุโดยตรง ตัวอย่างเช่น

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

อย่างไรก็ตามนั่นไม่สามารถใช้งานได้ในกรณีนี้เนื่องจาก ...

ประการที่สอง , ปลั๊กอิน Modal ถูกออกแบบมาเพื่อโหลดทรัพยากรระยะไกลในการสร้างของวัตถุ Modal ซึ่งหมายความว่าถ้ามีการเปลี่ยนแปลงไปoptions.remote, มันจะไม่โหลด

วิธีการรักษาง่ายๆคือการทำลายวัตถุ Modal ก่อนที่จะสลับในภายหลัง ทางเลือกหนึ่งคือการทำลายมันหลังจากที่ซ่อนเสร็จ:

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

หมายเหตุ:ปรับตัวเลือกตามต้องการ นี่คือทั่วไปมากที่สุด

Plunker

หรือคุณอาจลองใช้รูปแบบที่ซับซ้อนกว่านี้เพื่อทำสิ่งต่าง ๆ เช่นตรวจสอบว่าลิงก์ที่เปิดใช้งาน 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')ทำงานให้ฉันด้วยเงินทุน 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)...
Wojtek Kruszewski

171

สำหรับ bootstrap 3 คุณควรใช้:

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

17
ผู้กล้าของฉัน. รักการเปลี่ยนแปลงที่ไม่มีเอกสารเหล่านี้
Jorin

2
สิ่งนี้ช่วยได้มาก Bootstrap 3 ไม่เข้ากันได้แบบย้อนกลับและเนื้อหาส่วนใหญ่ใน SO (หรือฟอรัมอื่น ๆ ) นั้นเกี่ยวกับ BS <3 การลองใช้วิธีแก้ปัญหาเหล่านั้นเสียเวลามากอย่างแน่นอน
Swapnil

7
ไม่สมบูรณ์แบบ: มันแสดงเนื้อหาเก่าก่อนเนื้อหาใหม่สั้น ๆ
Laurent

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();
});

บนหน้ารีโมตตรวจสอบให้แน่ใจว่าคุณไม่ได้โหลด bootstrap หรือ jquery libraries มันจะฆ่าการอ้างอิงใด ๆ และทำให้คุณว่างเปล่าเป็นโมดัลที่ว่างเปล่า
Bankzilla

นี่ไม่ได้ผลสำหรับฉัน นี่คือรหัสของฉันที่ใช้งานได้: $ (เอกสาร) .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();มันก็เหมือนกับคำกริยาของฉันถูกซ่อนอยู่และมีเพียงการซ้อนทับสีเทาเท่านั้นที่ปรากฏ
Axel

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


7

โครงการของฉันถูกสร้างขึ้นใน Yii และใช้ปลั๊กอิน Bootstrap-Yii ดังนั้นคำตอบนี้จะเกี่ยวข้องเฉพาะเมื่อคุณใช้ Yii

การแก้ไขด้านบนไม่ทำงาน แต่หลังจากครั้งแรกที่แสดงคำกริยา ครั้งแรกที่มันว่างเปล่า ฉันคิดว่าเป็นเพราะหลังจากการเริ่มต้นโค้ด Yii เรียกใช้ฟังก์ชัน hide ของ modal ดังนั้นการล้างตัวแปรการเริ่มต้นของฉัน

ฉันพบว่าการวางการเรียก removeData ในทันทีก่อนที่รหัสที่เปิดตัว modal จะหลอกลวง ดังนั้นรหัสของฉันมีโครงสร้างเช่นนี้ ...

$ ("#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 เพียงแค่ใช้ "[บางสิ่งบางอย่าง modal" เป็น ID ของ modal 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') ผนวก hal box html


2
นี่เป็นสิ่งเดียวที่ทำงานกับฉันด้วย BS 3.3.6 ยังใช้เทมเพลตแฮนด์บาร์ ฉันแนะนำให้ใช้เอกสารแทนตัวถังอย่างไรก็ตาม
dbinott

1

การเพิ่ม $ (นี่) .html (''); เพื่อล้างข้อมูลที่มองเห็นได้เช่นกันและใช้งานได้ดี


1

หากมีการให้ URL ระยะไกลเนื้อหาจะถูกโหลดหนึ่งครั้งผ่านวิธีการโหลดของ jQuery และส่งไปยัง div .modal-content หากคุณกำลังใช้ data-api คุณสามารถใช้แอตทริบิวต์ href เพื่อระบุแหล่งที่มาระยะไกล ตัวอย่างนี้แสดงไว้ด้านล่าง

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

1

ฉันได้เพิ่มบางอย่างเช่นนี้เนื่องจากเนื้อหาที่เก่ากว่าจะปรากฏขึ้นจนกว่าเนื้อหาใหม่จะปรากฏขึ้นโดยมี. html ('') ภายในเนื้อหา. mod จะล้าง 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')
  })

(เพิ่มระยะห่างพิเศษเพื่อความชัดเจน)

วิธีนี้จะช่วยป้องกันไม่ให้แฟลชที่ไม่พึงประสงค์ของเนื้อหาโมดอลเก่าโดยการเรียกว่าง () บนคอนเทนเนอร์โมดัลรวมถึงการลบข้อมูล




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

องค์ประกอบ html ใดที่คุณต้องการว่างเช่น (div, ขยายอะไรก็ตาม)


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 นอกจากนี้ยังตรวจสอบว่ามีการโหลด modal ที่ซ่อนอยู่จากแหล่งข้อมูลระยะไกลและล้างเนื้อหาเก่าเพื่อป้องกันไม่ให้กระพริบ

$(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 เพื่อลบข้อมูลทั้งหมดที่แนบกับองค์ประกอบนั้น เท่าปัญหาของ OP เป็นห่วง.removeData('bs.modal')หรือ.removeData('modal')จะพอเพียงและมีความปลอดภัยมาก
Julian Paolo Dayag

-4

ขอให้โชคดีกับสิ่งนี้:

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

2
นี่ไร้ประโยชน์ การโหลดหน้าซ้ำไม่ใช่วิธีแก้ปัญหา
dbinott
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.