การใช้งาน Javascript เมื่อเพิ่มวิดเจ็ตใน Backend


20

ฉันมีวิดเจ็ตที่มีตัวควบคุมจาวาสคริปต์แนบมาด้วย

หากวิดเจ็ตปรากฏขึ้นเมื่อโหลดหน้าผู้ดูแลระบบวิดเจ็ตตัวควบคุมจะทำงานอย่างถูกต้อง

เมื่อฉันเพิ่มวิดเจ็ตใหม่มันไม่ทำงานอย่างถูกต้องฉันได้รับมาร์กอัป แต่ไม่มีเหตุการณ์จาวาสคริปต์ที่จะมีผล

ถ้าฉันบันทึกวิดเจ็ตใหม่เมื่อรีโหลดแบบฟอร์มตัวควบคุมจะถูกสร้างขึ้นอย่างถูกต้องและตอนนี้ทำงานได้

การรีเฟรชหน้ายังช่วยแก้ไขปัญหา แต่สำหรับวิดเจ็ตที่มีอยู่เท่านั้น วิดเจ็ตใหม่ยังคงมีปัญหานี้อยู่

โดยเฉพาะฉันกำลังเรียกใช้เลือกในอินพุตที่เลือกที่จุดเหล่านี้:

  • เอกสารพร้อม
  • ajaxComplete

ฉันตรวจสอบแล้วว่ารหัสของฉันทำงานในแต่ละกิจกรรมตามต้องการ แต่ผลลัพธ์ไม่เป็นไปตามที่คาดไว้

นี่คือปลั๊กอินทดสอบที่แสดงถึงปัญหา:

https://gist.github.com/Tarendai/8466299

คุณจะเห็นว่าฉันมีเคาน์เตอร์ที่เพิ่มขึ้นทุกองค์ประกอบที่เลือกพบว่ามันสามารถแปลงได้

หมายเหตุ:

  • เมื่อหน้าวิดเจ็ตโหลดฉันสามารถเห็นตัวนับเพิ่มขึ้นในคอนโซล JS ตามที่คาดไว้
  • เมื่อฉันเพิ่มวิดเจ็ตใหม่รหัสจะถูกรัน แต่มันล้มเหลวในการค้นหาองค์ประกอบที่เลือกใด ๆ ที่มันสามารถทำงานได้ตามที่แสดงโดย found.length ที่ 0 ซึ่งไม่ควรเป็นเช่นนี้เพราะวิดเจ็ตใหม่ทุกประเภทนั้นควร มีองค์ประกอบที่เลือก
  • อิลิเมนต์ที่เลือกมีคลาสที่จะระบุคลาสนี้จะถูกลบออกเมื่อมีการใช้ไลบรารีเลือกเพื่อป้องกันการทำซ้ำและการประมวลผลซ้ำบนวิดเจ็ตที่มีอยู่
  • ก่อนที่จะใช้ selectize ฉันใช้ Select2 ซึ่งมีปัญหาเดียวกัน
  • การแสดงความคิดเห็นรหัส AJAX ฉันคาดหวังว่าวิดเจ็ตใหม่จะมีอินพุตเลือกแบบมาตรฐาน พวกเขาไม่ได้. ฉันไม่รู้ว่าทำไมในกรณีนี้

ดังนั้นฉันจะทำให้ตัวเลือกควบคุมทำงานโดยไม่บอกผู้ใช้ให้รีเฟรช / คลิกบันทึกก่อนทำการเปลี่ยนแปลงได้อย่างไร


มันเป็นปัญหาการมอบหมายกิจกรรม คุณจะต้องมองหา.on()วิธีการใช้ jQuerys ซึ่งต้องการให้คุณผูกเหตุการณ์กับเอกสาร อย่างไรก็ตามเหตุการณ์ใดที่จะเหมาะสมฉันไม่แน่ใจในตอนนี้ ในที่สุดก็เป็นเพราะการผูกเดิมของคุณเป็นตัวแทนของรุ่นเริ่มต้นของ DOM เมื่อหน้าโหลดและส่วนใหญ่จะตาบอดองค์ประกอบใหม่ (เนื้อหาวิดเจ็ต) ที่จะถูกเพิ่มผ่านทางอาแจ็กซ์ หวังว่าจะชี้ให้คุณในทิศทางที่ถูกต้องถ้าไม่ฉันสามารถตอบได้ดีขึ้นเมื่อฉันทำงาน

นี่คือสิ่งที่ฉันคาดไว้และทำไมฉันจึงเพิ่มชิ้นjQuery( document ).ajaxStop( function() {ส่วนเพื่อที่ฉันจะสามารถเริ่มต้นการควบคุมในวิดเจ็ตที่โหลดใหม่ อย่างไรก็ตามหากฉันลบบรรทัดนั้นฉันคาดว่าวิดเจ็ตใหม่จะมีอินพุตเลือก HTML มาตรฐาน แต่พวกเขาจะไม่ = s
Tom J Nowell

ตามที่ @ aaron-holbrook แสดงความคิดเห็นวิธีการเป็นวิธีที่สะอาดที่สุดโดยใช้widget-updatedและwidget-addedกิจกรรม นอกจากนี้ผมอยากจะเน้นในรหัส @michaeljames ใช้ของ #widgets-rightid ตรวจสอบให้แน่ใจว่าได้ใช้เพื่อกำหนดเป้าหมายองค์ประกอบวิดเจ็ตที่ใช้งานอยู่ภายในรหัส JS ของคุณมิฉะนั้นคุณอาจได้รับองค์ประกอบที่ซ้ำกันเนื่องจากรหัสของคุณอาจเลือกองค์ประกอบวิดเจ็ตที่ไม่ได้ใช้งานที่ซ่อนอยู่ทางด้านซ้ายของหน้าจอ
Julien

คำตอบ:


12

ข่าวดี,

ฉันแก้ไขมันแล้ว

ขอโทษที่ไม่มีส่วนสำคัญของคุณในความคิดเห็นเริ่มต้นของฉันและให้คำตอบที่คุณได้ดำเนินการแล้ว นั่นจะสอนให้ฉันตอบโทรศัพท์บนรถไฟ

การใช้ ajaxstop ของคุณถูกต้อง นรก JS ส่วนใหญ่ทำงานอย่างถูกต้องคุณสามารถดูสไตล์ css ที่เริ่มต้นและการเปลี่ยนแปลงใน DOM

ปัญหาเกิดขึ้นกับตัวเลือกของคุณ

นี่เป็นเพราะเนื้อหาวิดเจ็ตไม่ได้ถูกโหลดผ่าน ajax จริงๆแล้วมันจะทำการโคลนนิ่งจากคอลัมน์ด้านซ้ายมือที่มันถูกซ่อนไว้และจากนั้นจะทำการโทร ajax เพื่อบันทึกตำแหน่งของวิดเจ็ตในคอลัมน์ขวามือ สิ่งนี้อธิบายได้ว่าทำไม ajaxstop จึงปฏิบัติได้แม้ว่าเนื้อหาจะถูกโคลน อย่างไรก็ตามเนื่องจากมีวิดเจ็ตรุ่นที่ซ่อนอยู่ในคอลัมน์ด้านซ้าย JS ของคุณกำลังสร้างอินสแตนซ์นั้น เช่นนี้เมื่อคุณลากไปยังคอลัมน์ด้านขวาคุณจะได้รับโคลนแบบ mangled ของวิดเจ็ตที่ซ่อนอยู่

ดังนั้นคุณต้องเลือกอันที่ด้านซ้าย ด้านล่างเป็นรหัสที่ถูกต้อง:

<script>
jQuery( document ).ready( function( $ ) {
    function runSelect() {
        var found = $( '#widgets-right select.testselectize' );
        found.each( function( index, value ) {

            $( value ).selectize();
                .removeClass( 'testselectize' )
                .addClass( 'run-' + window.counter );

            console.log( $val );
            window.counter++;
        } );
    }

    window.counter = 1;

    runSelect();

    $( document ).ajaxStop( function() {
        runSelect();
    } );
} );
</script>

moly ศักดิ์สิทธิ์ฉันต้องไปทดสอบ <3
Tom J Nowell

วิธีแก้ปัญหาอาการปวดศีรษะที่สำคัญมาก!
bosco

3
ฉันจะแนะนำไม่ให้ทำงานในทุก ๆ เหตุการณ์ 'ajaxStop' และแทนที่จะแนะนำให้ใช้ใน 'เพิ่มวิดเจ็ต' รวมถึงเหตุการณ์ 'อัพเดตวิดเจ็ต'
Tyrun

16

ในฐานะที่ @ aaron-holbrook แสดงความคิดเห็นวิธีการทำความสะอาดจะทำ:

jQuery(document).on('widget-updated widget-added', function(){
    // your code to run
});

ในหลายกรณีคุณจะต้องเรียกใช้ JS เมื่อหน้าโหลดเช่นเดียวกับเมื่อวิดเจ็ตมีการปรับปรุง คุณอาจทำเช่นนี้

function handle_widget_loading(){
   // your code to run
}
jQuery(document).ready( handle_widget_loading );
jQuery(document).on('widget-updated widget-added', handle_widget_loading );

เพียงวางที่นี่เพื่ออ้างอิงเนื่องจากคำตอบนั้นง่ายกว่ามากในการค้นหาความคิดเห็น


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