Как я могу контролировать порядок Drupal.behaviors?


9

Я хочу, чтобы код JavaScript из модуля X запускался только после запуска кода из модуля Y. Какой лучший способ сделать это?

Ответы:


5

Код JavaScript, используемый Drupal 7, выглядит следующим образом:

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 использует похожий код:

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

Если JavaScript гарантирует, что свойства объекта / массива всегда будут проходить в том же порядке, в котором они были добавлены, тогда значения будут переданы jQuery.each()функции, используемой в качестве ее второго параметра, в том же порядке, в котором они вставлены в массив, переданный в качестве первого параметра.
Это будет означать, что первое вставленное поведение Drupal.behaviorsвыполняется первым.
В этом случае, чтобы разрешить выполнение действий, определенных вашим модулем, вы можете использовать для него меньший вес. Если вы хотите, чтобы они выполнялись раньше других, вес модуля должен быть установлен на -50; другие значения тоже могут работать. Если вы используете Drupal 7, drupal_add_js ()позволяет связать вес с кодом JavaScript; Сначала в выводе HTML появляется код JavaScript с меньшим весом. Это невозможно с Drupal 6, подумал.

JavaScript не гарантирует, что свойства просматриваются в том же порядке, в котором они были добавлены. Это означает, что разные реализации JavaScript будут представлять одни и те же свойства в другом порядке; это также означает, что один и тот же порядок может изменяться в разных версиях одного и того же браузера.


Однажды я нашел страницу, в которой указан вес, используемый некоторыми модулями. Я не помню URL этой страницы, и если страница включала только определенные модули, или она была исчерпывающей. Если я найду эту страницу, я сообщу здесь ссылку.
kiamlaluno

1
Вы всегда можете просто проверить в системной таблице - попробуйтеselect name, weight from system where type = 'module' order by weight ASC, name
cam8001

К сожалению, мне нужен PHP моего модуля (mymodule) для запуска до PHP другого модуля (vertical_tabs), а JS моего модуля для запуска после js vertical_tab. Есть ли способ определения поведения, основанный исключительно на javascript?
cam8001

@ cam8001: Я знаю это, но это будет означать, что вы должны установить все модули, чтобы знать меньший вес, используемый модулем. На странице, которую я нашел, перечислены весы модулей, и это может быть полезно, когда вам нужно знать, какой вес вы должны назначить своему модулю для выполнения перед каждым модулем. Я знаю, вы могли бы просто использовать чрезвычайно легкий вес, но вы бы использовали вес, который легче, чем это необходимо.
kiamlaluno

@ cam8001: В этом случае нет способа выполнить то, что вы пытаетесь сделать, кроме как изменить порядок объектов, содержащихся в Drupal.behaviors; как я сообщал, $.each(Drupal.behaviors)списки объектов в том же порядке, в котором они вставлены, не основаны на их идентификаторе.
kiamlaluno

5

Используйте модуль Behavior Weights .
(Пожалуйста, дайте ему некоторое тестирование, прежде чем использовать его на производственной площадке)

Модуль позволяет привязывать веса к поведению, а затем он перехватывает / заменяет drupal.attachBehaviorsпользовательскую реализацию, которая учитывает веса.


Почему бы не использовать модульный вес, как предлагается в другом ответе?

  • Вес модуля довольно тяжелый инструмент. Это относится ко всем реализациям ловушек (php) и поведениям (js) модуля, в то время как нас интересует только одно поведение.
  • порядок свойств в объекте js не гарантируется спецификацией (хотя он реализован так, как вы ожидаете почти во всех браузерах).

См. Предсказуем
ли порядок полей в объекте javascript при прохождении через них? и
порядок элементов - для цикла (… in…) в javascript .


@kiam, если бы я сделал это модулем «поведенческий вес» («bewgt») на drupal.org, вы бы присоединились в качестве со-сопровождающего? Вероятно, это будет довольно маленький модуль, но, вероятно, лучше, чем позволить ему поставляться с чем-то другим. У меня есть пример реализации локально для D6, кажется, работает.
Donquixote

только что сделал .. вы все еще приглашены :)
Donquixote

drupal.org/node/1302126 - Я надеюсь, что это будет в ядре в D8 :)
donquixote

Это был бы интересный модуль, но я должен сначала обновить код некоторых из моих модулей, для которых я не писал ни строчки кода из возрастов. После этого я могу быть свободным для совместной разработки нового модуля.
kiamlaluno

Просто говорю, что люди просят варианты использования. drupal.org/node/1302126#comment-5911632
donquixote

0

Для Drupal 6 -

Простое решение, если это не нужно переносить, это поместить JS, который вы хотите запустить последним, в файл theme.php темы. Тема вызовов drupal_add_js всегда вызывается после модулей.

Если он действительно должен быть переносимым, самое «чистое» решение в drupal 6 - добавить новый модуль, который имеет другой вес, чем ваш модуль с php. Вы могли бы даже иметь два модуля в одной папке, сделать первый модуль зависимым от первого и настроить веса в хуках установки / обновления. Ничего из этого не требуется, просто облегчает установку.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.