it-swarm-ko.tech

성공적인 Ajax 후 Drupal.attachBehaviors를 트리거하는 방법

링크를 클릭하면 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) $.fn.mymodule 함수와 연결된 $ ajax_commands 배열에 ajax_command_invoke(NULL, 'mymodule');을 추가하십시오

(b) 내 자바 스크립트에 $('body').ajaxSuccess(Drupal.attachBehaviors);을 추가하십시오. ajaxComplete도 시도했습니다. 문서에서도 시도했습니다.

(c) 여기에 설명 된대로 사용자 정의 명령을 작성하십시오 http://www.jaypan.com/tutorial/calling-function-after-ajax-event-drupal-7

참고 : 새 html을 삽입/수정하기 위해 클릭 할 때마다 attachBehaviors를 트리거하는 문제 일뿐입니다. 링크를 클릭 한 다음 콘솔에 Drupal.attachBehaviors ()를 입력하면 'middone'클래스가 추가 된 것으로 확인 된대로 내 JavaScript로 링크가 다시 처리되고 다시 클릭 될 수 있습니다.

참고 : 또한 흥미롭게도 $ajax_commands를 비워두고 콜백 함수의 끝에서 반환 (빈 배열)하면 첫 번째 및 후속 클릭에서 링크를 클릭 할 수 있습니다. 내가 찾고있는 기능 (토글)이 있습니다. 그러나 클릭 할 때마다 HTML이 변경되지 않으므로 사용자가 전환이 켜져 있는지 여부를 알 수있는 방법이 없습니다.

모든 조언을 주시면 감사하겠습니다.

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

부분 답변 :

Drupal ajax.js 성공 함수는 양식에 대한 동작 만 다시 첨부합니다.

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

그래서 나는 모든 아약스 객체의 성공 함수를 해킹하기로 결정했습니다.

자바 스크립트는 이제

    (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의 기본값을 복사하여 붙여 넣습니다. 어떤 이유로 Drupal.attachBehaviors는 타이머 내에 있어야합니다. 내가 무시한 이유 때문에 그 자체로 가질 수는 없습니다.

누군가가 더 우아한 해결책을 찾거나 타이머 이상한 점을 설명 할 수있는 경우를 대비 하여이 질문을 거의 열어 두지 않을 것입니다.

많은 감사

10
JSL

일부 디버깅 후 문제가 내 코드와 관련이 없음을 깨달았습니다.

문제는 다른 모듈, 내 경우에는 자체 동작 기능에서 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

내 솔루션은 컬러 박스 모듈을 비활성화하는 것이 었습니다.

도와 주신 모든 분들께 감사드립니다.

1
JSL

첫 번째 답변 은 말할 수 없지만 설정에서 색상 상자의 속성을 설정할 수 있습니다. 예를 들면 다음과 같습니다.

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'
});
1
Ilya Krigouzov

Ajax 요청 자체에서 리턴되는 컨텐츠에 Ajax 동작을 첨부하는 것은 까다로울 수 있습니다. 그러나 가능합니다.

Hook_menu 코드 스 니펫이 정확하지 않다고 가정하면 ($ items를 반환하고 함수가 닫힙니다.)-콜백을 '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;

}
1
David Thomas