Jak mogę kontrolować kolejność Drupal.behaviors?

9

Chcę, aby kod JavaScript z modułu X działał tylko po uruchomieniu kodu z modułu Y. Jak najlepiej to zrobić?

cam8001
źródło

Odpowiedzi:

5

Kod JavaScript używany przez Drupal 7 jest następujący:

Drupal.attachBehaviors = function (context, settings) {
  context = context || document;
  settings = settings || Drupal.settings;
  // Execute all of them.
  $.each(Drupal.behaviors, function () {
    if ($.isFunction(this.attach)) {
      this.attach(context, settings);
    }
  });
};

Drupal 6 używa podobnego kodu:

Drupal.attachBehaviors = function(context) {
  context = context || document;
  if (Drupal.jsEnabled) {
    // Execute all of them.
    jQuery.each(Drupal.behaviors, function() {
      this(context);
    });
  }
};

Jeśli JavaScript zagwarantuje, że właściwości obiektów / tablic są zawsze przeglądane w tej samej kolejności, w jakiej są dodawane, wówczas wartości byłyby przekazywane jQuery.each()do funkcji użytej jako drugi parametr w tej samej kolejności, w jakiej są wstawiane do tablicy przekazywanej jako pierwszy parametr.
Oznaczałoby to, że pierwsze wprowadzone zachowanie Drupal.behaviorsjest wykonywane jako pierwsze.
W takim przypadku, aby umożliwić wykonanie zachowań zdefiniowanych przez moduł, możesz użyć do tego mniejszej wagi. Jeśli chcesz, aby były wykonywane przed innymi, waga modułu powinna być ustawiona na -50; inne wartości też mogą działać. Jeśli używasz Drupal 7, drupal_add_js ()pozwala powiązać wagę z kodem JavaScript; Kod JavaScript o mniejszej wadze pojawia się jako pierwszy na wyjściu HTML. Nie jest to możliwe w przypadku Drupala 6, pomyślał.

JavaScript nie gwarantuje przejścia przez właściwości w tej samej kolejności, w jakiej zostały dodane. Oznacza to, że różne implementacje JavaScript prezentowałyby te same właściwości przy użyciu innej kolejności; oznacza to również, że ta sama kolejność może ulec zmianie w różnych wersjach tej samej przeglądarki.

kiamlaluno
źródło
Kiedyś znalazłem stronę, na której wymieniono wagę używaną przez niektóre moduły. Nie pamiętam adresu URL tej strony, a jeśli strona zawierała tylko określone moduły lub była wyczerpująca. Jeśli znajdę tę stronę, zgłoś tutaj link.
kiamlaluno
1
Zawsze możesz po prostu sprawdzić w tabeli systemowej - spróbujselect name, weight from system where type = 'module' order by weight ASC, name
cam8001
Niestety, potrzebuję PHP mojego modułu (mymodułu), aby działał przed PHP drugiego modułu (vertical_tabs), ale JS mymodułu działa po js vertical_tab. Czy istnieje sposób na zachowanie wagi wyłącznie w oparciu o javascript?
cam8001
@ cam8001: Wiem o tym, ale to by oznaczało, że powinieneś zainstalować wszystkie moduły, aby poznać mniejszą wagę używaną przez moduł. Na stronie, którą znalazłem, wymieniono wagi modułów i może być przydatna, gdy trzeba wiedzieć, jaką wagę należy przypisać do modułu, który ma zostać wykonany przed każdym modułem. Wiem, możesz po prostu użyć wyjątkowo lekkiej wagi, ale użyłbyś ciężaru, który jest lżejszy niż jest potrzebny.
kiamlaluno
@ cam8001: W takim przypadku nie można osiągnąć tego, co próbujesz zrobić, poza zmianą kolejności obiektów w nim zawartych Drupal.behaviors; jak zgłosiłem, $.each(Drupal.behaviors)wyświetla listę obiektów w tej samej kolejności, w jakiej zostały wstawione, nie na podstawie ich identyfikatora.
kiamlaluno
5

Użyj modułu Behavior Weights .
(Proszę przetestować go przed użyciem go na stronie produkcyjnej)

Moduł pozwala przypisywać wagi do zachowań, a następnie przejmuje / zastępuje drupal.attachBehaviorsniestandardową implementacją, która szanuje wagi.


Dlaczego nie zamiast tego waga modułu, jak sugerowano w drugiej odpowiedzi?

  • masa modułu jest dość ciężkim narzędziem. Dotyczy to wszystkich implementacji przechwytujących (php) i zachowań (js) modułu, podczas gdy interesuje nas tylko jedno zachowanie.
  • kolejność właściwości w obiekcie js nie jest gwarantowana przez specyfikację (chociaż jest implementowana zgodnie z oczekiwaniami w prawie wszystkich przeglądarkach).

Zobacz:
Czy kolejność pól w obiekcie javascript jest przewidywalna podczas zapętlania ich? i
Kolejność elementów - dla (… w…) pętli w javascript .

Don Kichot
źródło
@kiam, jeśli uczynię to modułem „wagą behawioralną” („bewgt”) na drupal.org, czy przyłączysz się jako współ-opiekun? Prawdopodobnie będzie to dość mały moduł, ale prawdopodobnie lepszy niż pozwolić, aby został dostarczony z czymś innym. Mam przykładową implementację lokalnie dla D6, wydaje się działać.
donquixote
właśnie to zrobiłem .. wciąż jesteś zaproszony :)
donquixote
drupal.org/node/1302126 - Mam nadzieję, że będzie to rdzeń w D8 :)
donquixote
Byłby to interesujący moduł, ale muszę najpierw zaktualizować kod niektórych moich modułów, dla których nie napisałem wiersza kodu od wieków. Potem mógłbym być wolny za wspólne opracowywanie nowego modułu.
kiamlaluno
Po prostu ludzie pytają o przypadki użycia. drupal.org/node/1302126#comment-5911632
donquixote
0

Dla Drupal 6 -

Prostym rozwiązaniem, jeśli nie musi być przenośne, jest umieszczenie pliku JS, który chcesz uruchomić jako ostatni w pliku theme.php. Wywołania tematyczne drupal_add_js są zawsze wywoływane po modułach.

Jeśli musi być przenośny, „najczystszym” rozwiązaniem w drupal 6 jest dodanie nowego modułu, który ma inną wagę niż twój moduł z php. Możesz nawet mieć dwa moduły w tym samym folderze, uzależnić pierwszy moduł od pierwszego i dostosować wagi w zaczepach instalacji / aktualizacji. Żadne z nich nie jest konieczne, po prostu ułatwia instalację.

mirzu
źródło