วิธีเรียกใช้ Drupal.attachBehaviors หลังจาก Ajax ที่ประสบความสำเร็จ


10

ฉันมีโมดูลที่อัพเดตโหนดผ่าน ajax เมื่อมีการคลิกลิงก์

ลิงค์คือสลับคุณควรอัปเดตโหนดด้วยค่า 1 ในการคลิกครั้งแรกจากนั้นตามด้วยค่า 0 ในการคลิกครั้งต่อไป ฯลฯ เช่นเดียวกับการเปิด / ปิดบางสิ่งบางอย่าง

รหัสด้านล่างใช้งานได้ในการคลิกครั้งแรกหลังจากโหลดหน้าเว็บ แต่ไม่สามารถคลิกครั้งต่อไปได้ ฉันเชื่อว่า Drupal.attachBehaviors ต้องถูกเรียก / เรียกใช้หลังจากการคลิกแต่ละครั้ง แต่ฉันไม่สามารถหาวิธีการทำสิ่งนี้ได้

  1. โมดูล

    function mymodule_menu() {
      $items['mypath/%/%/ajax'] = array(
      'title' => 'My title',
      'page callback' => 'mymodule_ajax_callback',
      'page arguments' => array(1,2),
      'access arguments' => array('access content'),
      'type' => MENU_CALLBACK,
      );
    
      ...
    }
    
    function mymodule_ajax_callback($id, $status) {
      //Validation[...]
    
      //Node Update using $id as the nid and $status as the field value[...]
    
      // Define a new array to hold our AJAX commands.
      $ajax_commands = array();
    
      // Create a new AJAX command that replaces the #div.
      $replacedivid = '#status'.$id;
      $replacestring = '<div id="status'.$id.'"><a data-url="'.base_path().'mypath/'.$id.'/'.$new_status.'/ajax" title="This item is marked as '.$status_text.'" id="statuslink'.$id.'" class="midui">'.$status_text.'</a></div>';
    
    
      $ajax_commands[] = ajax_command_replace($replacedivid, $replacestring);
    
    
      return drupal_json_output($ajax_commands);
    }
    
  2. จาวาสคริ

    (function ($) {
      Drupal.behaviors.mymodule = {
        attach: function(context, settings) {
          var $uilink = $('.midui'); //find all links
    
          for (var i=0;i<$uilink.length;i++) { //Loop
            var $link = $('#' + $uilink[i].id);
            if (!$link.hasClass("middone")) {
    
              new Drupal.ajax('#' + $uilink[i].id, $link, {
                url: $link.attr('data-url'),
                effect: 'fade',
                settings: {},
                progress: {
                  type: 'throbber'
                },
                event: 'click tap'
              });
    
              $link.addClass("middone"); //add class when we're done
    
            }
          }
        }
      }
    })(jQuery);
    
  3. สิ่งที่ฉันได้ลองไปแล้ว:

(a) เพิ่ม a ajax_command_invoke(NULL, 'mymodule');$ ajax_commands array ควบคู่กับ$.fn.mymoduleฟังก์ชั่น

(b) เพิ่ม$('body').ajaxSuccess(Drupal.attachBehaviors);ในจาวาสคริปต์ของฉัน ajaxComplete พยายามเช่นกัน ลองใช้กับเอกสารด้วย

(c) สร้างคำสั่งที่กำหนดเองตามรายละเอียดที่นี่http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7

หมายเหตุ: ฉันรู้ว่ามันเป็นเพียงเรื่องของการเรียก attachBehaviors หลังจากแต่ละคลิกเพื่อ 'ajaxify' html ใหม่ที่ถูกแทรก / แก้ไข หากฉันคลิกที่ลิงก์จากนั้นพิมพ์ Drupal.attachBehaviors () ในคอนโซลลิงก์ของฉันจะถูกประมวลผลอีกครั้งโดย javascript ของฉันดังที่เห็นได้จากการเพิ่มคลาส 'middone' และสามารถคลิกได้อีกครั้ง

หมายเหตุ: นอกจากนี้ที่น่าสนใจถ้าฉันปล่อยให้$ajax_commandsว่างไว้และส่งคืน (อาร์เรย์ว่าง) ที่ท้ายฟังก์ชั่นการโทรกลับลิงก์จะยังคงสามารถคลิกได้ในการคลิกครั้งแรกและครั้งต่อไป มันจะมีฟังก์ชั่นที่ฉันกำลังมองหา (สลับ) อย่างไรก็ตามเนื่องจากไม่มีการเปลี่ยนแปลงใด ๆ กับ html หลังจากการคลิกแต่ละครั้งจึงไม่มีวิธีใดที่ผู้ใช้จะสามารถทราบได้ว่าสวิตช์เปิดหรือปิดอยู่

พอยน์เตอร์ใด ๆ จะได้รับการชื่นชมอย่างมาก

================================================== =====

คำตอบบางส่วน:

ฟังก์ชั่นความสำเร็จของ Drupal ajax.js จะแนบเฉพาะพฤติกรรมอีกครั้งสำหรับแบบฟอร์ม (ฉันคิดว่า?)

    if (this.form) {
      var settings = this.settings || Drupal.settings;
      Drupal.attachBehaviors(this.form, settings);
    }

ดังนั้นฉันจึงตัดสินใจแฮ็คฟังก์ชั่นความสำเร็จของวัตถุ ajax ทั้งหมดของฉัน

ตอนนี้ Javascript กลายเป็น

    (function ($) {
      Drupal.behaviors.mymodule = {
        attach: function(context, settings) {
          var $uilink = $('.midui'); //find all links

          for (var i=0;i<$uilink.length;i++) { //Loop
            var $link = $('#' + $uilink[i].id);
            if (!$link.hasClass("middone")) {

              myAjax = new Drupal.ajax('#' + $uilink[i].id, $link, {
                url: $link.attr('data-url'),
                effect: 'fade',
                settings: {},
                progress: {
                  type: 'throbber'
                },
                event: 'click tap'
              });

              myAjax.options.success = function (response, status) {
                //Trigger Attach Behaviors
                setTimeout(function(){Drupal.attachBehaviors($(myAjax.selector))}, 0);
                // Sanity check for browser support (object expected).
                // When using iFrame uploads, responses must be returned as a string.
                if (typeof response == 'string') {
                  response = $.parseJSON(response);
                }

                return myAjax.success(response, status);
              }

              $link.addClass("middone"); //add class when we're done

            }
          }
        }
      }
    })(jQuery);

ฟังก์ชั่นความสำเร็จคือการคัดลอกวางของเริ่มต้นจาก ajax.js ด้วยสายการเพิ่มสำหรับพฤติกรรม reattaching ด้วยเหตุผลบางอย่างDrupal.attachBehaviorsต้องอยู่ภายในตัวจับเวลา ฉันไม่สามารถทำได้ด้วยตัวเองด้วยเหตุผลที่ฉันเพิกเฉย

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

ขอบคุณมาก


ทำไมคุณต้องการแนบพฤติกรรมครั้งแล้วครั้งเล่า องค์ประกอบเหล่านี้จะถูกเรียกใช้ซ้ำโดยอัตโนมัติในองค์ประกอบใหม่ใด ๆ ที่สร้างขึ้นโดยใช้ AJAX ดังนั้นทำไมจึงไม่เพียงพอ
Mołot

พฤติกรรมจะไม่ถูกจัดใหม่ในกรณีของฉันโดยอัตโนมัติ ขอบคุณ
JSL

คำตอบ:


1

มันอาจเป็นเรื่องยากในการแนบพฤติกรรมอาแจ็กซ์กับเนื้อหาที่ส่งคืนจากคำขออาแจ็กซ์เอง อย่างไรก็ตามมันเป็นไปได้

แม้ว่าข้อมูลโค้ด hook_menu ของคุณจะดูไม่สมบูรณ์ แต่สมมติว่าถูกต้อง (ส่งคืน $ รายการและฟังก์ชั่นปิด) - ในกรณีของคุณคุณอาจต้องปรับเปลี่ยนการจัดส่งกลับไปที่ 'ajax_deliver'

เช่น:

/**
 * Implements hook_menu
 */
function mymodule_menu() {

  $items['mypath/%/%/ajax'] = array(
    'title' => 'My title',
    'page callback' => 'mymodule_ajax_callback',
    'page arguments' => array(1,2),
    'access arguments' => array('access content'),
    'delivery callback' => 'ajax_deliver',
    'theme callback' => 'ajax_base_page_theme',
    'type' => MENU_CALLBACK,
  );

  return $items;

}

ขอบคุณสำหรับคำแนะนำ แต่มันก็ใช้งานไม่ได้เช่นกัน ฉันใช้รหัสของคุณใน hook_menu และพฤติกรรมจะไม่ติดใหม่โดยอัตโนมัติ
JSL

1

หลังจากแก้จุดบกพร่องบางอย่างฉันรู้ว่าปัญหาไม่ได้อยู่กับรหัสของฉัน

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

ข้อผิดพลาด colorbox: เป็น 7.24

Uncaught TypeError: Cannot read property 'transition' of undefined colorbox_inline.js?

และใน 7.25

Uncaught TypeError: Cannot read property 'mobiledetect' of undefined

ทางออกของฉันคือการปิดการใช้งานโมดูล colorbox

ขอบคุณมากสำหรับทุกคนที่ช่วย


1

ฉันไม่สามารถแสดงความคิดเห็นคำตอบแรกแต่คุณสามารถตั้งค่าคุณสมบัติสำหรับ colorbox ในการตั้งค่า ตัวอย่างเช่น:

myAjax = new Drupal.ajax('#' + $uilink[i].id, $link, {
  url: $link.attr('data-url'),
  effect: 'fade',
  settings: {
    colorbox: {
      mobiledetect: false
    }
  },
  progress: {
    type: 'throbber'
  },
  event: 'click tap'
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.