¿Cómo puedo controlar el orden de los comportamientos de Drupal?


9

Quiero que el código JavaScript del módulo X se ejecute solo después de que se haya ejecutado el del módulo Y. ¿Cuál es la mejor manera de hacer esto?

Respuestas:


5

El código JavaScript utilizado por Drupal 7 es el siguiente:

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 usa un código similar:

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

Si JavaScript garantiza que las propiedades del objeto / matriz siempre se atraviesen en el mismo orden en que se agregan, los valores se pasarían jQuery.each()a la función utilizada como su segundo parámetro en el mismo orden en que se insertan en la matriz que se pasó como primer parámetro.
Esto significaría que el primer comportamiento insertado Drupal.behaviorsse ejecuta primero.
En este caso, para permitir que los comportamientos definidos por su módulo se ejecuten primero, puede usar un peso más ligero para él. Si desea que se ejecuten antes que los demás, el peso del módulo debe establecerse en -50; otros valores también pueden funcionar. Si está utilizando Drupal 7, drupal_add_js ()permite asociar un peso al código JavaScript; El código JavaScript con un peso más ligero aparece primero en la salida HTML. Esto no es posible con Drupal 6, pensó.

JavaScript no garantiza que las propiedades se atraviesen en el mismo orden en que se agregan. Esto significa que diferentes implementaciones de JavaScript presentarían las mismas propiedades usando un orden diferente; También significa que el mismo orden podría cambiar en diferentes versiones del mismo navegador.


Una vez encontré una página que enumeraba el peso utilizado por algunos módulos. No recuerdo la URL de esa página, y si la página incluía solo módulos particulares, o si era exhaustiva. Si encuentro esa página, informaré aquí el enlace.
kiamlaluno

1
Siempre puede verificar en la tabla del sistema - pruebeselect name, weight from system where type = 'module' order by weight ASC, name
cam8001

Desafortunadamente, necesito que el PHP de mi módulo (mymodule) se ejecute antes que el PHP de otro módulo (vertical_tabs), pero el JS de mymodule se ejecute después de js de vertical_tab. ¿Existe una forma puramente basada en JavaScript para ponderar los comportamientos?
cam8001

@ cam8001: Lo sé, pero eso significaría que debe instalar todos los módulos, para saber el peso más ligero utilizado por un módulo. La página que encontré enumeraba los pesos de los módulos, y podría ser útil cuando necesita saber qué peso debe asignar a su módulo para que se ejecute antes de cada módulo. Lo sé, simplemente podrías usar un peso extremadamente liviano, pero usarías un peso que sea más liviano de lo necesario.
kiamlaluno

@ cam8001: en ese caso, no hay forma de lograr lo que está tratando de hacer, excepto alterar el orden de los objetos contenidos en Drupal.behaviors; como informé $.each(Drupal.behaviors)enumera los objetos en el mismo orden en que se insertan, sin basarse en su identificador.
kiamlaluno

5

Use el módulo Pesos de comportamiento .
(Por favor, pruébelo antes de usarlo en un sitio de producción)

El módulo permite adjuntar pesos a los comportamientos, y luego secuestra / reemplaza drupal.attachBehaviorscon una implementación personalizada, que respeta los pesos.


¿Por qué no el peso del módulo, como se sugiere en la otra respuesta?

  • El peso del módulo es una herramienta bastante pesada. Se aplica a todas las implementaciones de enlace (php) y comportamientos (js) del módulo, mientras que solo estamos interesados ​​en un solo comportamiento.
  • el orden de las propiedades en un objeto js no está garantizado por la especificación (aunque se implementa como es de esperar en casi todos los navegadores).

Consulte
¿Es predecible el orden de los campos en un objeto javascript al recorrerlos? y
Orden de elementos: para (... en ...) bucle en javascript .


@kiam, si hago de este un módulo de "peso de comportamiento" ("bewgt") en drupal.org, ¿te unirías como co-mantenedor? Probablemente será un módulo bastante pequeño, pero probablemente mejor que dejar que se envíe con otra cosa. Tengo una implementación de muestra local para D6, parece funcionar.
donquixote

solo hecho .. usted todavía está invitado :)
DONQUIXOTE

drupal.org/node/1302126 - Espero que esto esté en el núcleo en D8 :)
donquixote

Sería un módulo interesante, pero primero tengo que actualizar el código de algunos de mis módulos, para lo cual no escribí una línea de código desde hace siglos. Después de eso, podría ser libre para desarrollar conjuntamente un nuevo módulo.
kiamlaluno

Solo digo, la gente está pidiendo casos de uso. drupal.org/node/1302126#comment-5911632
donquixote

0

Para Drupal 6 -

Una solución simple, si esto no necesita ser portátil, es colocar el JS que desea ejecutar en último lugar en el archivo template.php del tema. Las llamadas temáticas drupal_add_js siempre se llaman después de los módulos.

Si necesita ser portátil, la solución "más limpia" en drupal 6 es agregar un nuevo módulo que tenga un peso diferente al de su módulo con el php. Incluso podría tener los dos módulos en la misma carpeta, hacer que el primer módulo dependa del primero y ajustar los pesos en los ganchos de instalación / actualización. Ninguno de los cuales es necesario, solo facilita la instalación.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.