Come posso controllare l'ordine di Drupal.behaviors?


9

Voglio che il codice JavaScript del modulo X venga eseguito solo dopo che quello del modulo Y è stato eseguito. qual'è il miglior modo per farlo?

Risposte:


5

Il codice JavaScript utilizzato da Drupal 7 è il seguente:

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 utilizza un codice simile:

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

Se JavaScript garantirebbe che le proprietà degli oggetti / array siano sempre attraversate nello stesso ordine in cui vengono aggiunte, i valori sarebbero passati jQuery.each()alla funzione utilizzata come secondo parametro nello stesso ordine in cui sono inseriti nell'array passato come primo parametro.
Ciò significherebbe che il primo comportamento inserito Drupal.behaviorsviene eseguito per primo.
In questo caso, per consentire che i comportamenti definiti dal modulo vengano eseguiti per primi, è possibile utilizzare un peso più leggero. Se vuoi che vengano eseguiti prima degli altri, il peso del modulo dovrebbe essere impostato su -50; anche altri valori possono funzionare. Se stai usando Drupal 7, drupal_add_js ()consente di associare un peso al codice JavaScript; Il codice JavaScript con un peso inferiore appare per primo nell'output HTML. Questo non è possibile con Drupal 6, pensato.

JavaScript non garantisce che le proprietà vengano attraversate nello stesso ordine in cui vengono aggiunte. Ciò significa che diverse implementazioni JavaScript presenterebbero le stesse proprietà usando un ordine diverso; significa anche che lo stesso ordine potrebbe cambiare in diverse versioni dello stesso browser.


Una volta ho trovato una pagina che elencava il peso utilizzato da alcuni moduli. Non ricordo l'URL di quella pagina e se la pagina includeva solo moduli particolari o era esaustiva. Se trovo quella pagina, segnalerò qui il link.
kiamlaluno

1
Puoi sempre controllare nella tabella di sistema - provaselect name, weight from system where type = 'module' order by weight ASC, name
cam8001

Sfortunatamente ho bisogno che il PHP del mio modulo (mymodule) sia eseguito prima del PHP dell'altro modulo (vertical_tabs), ma il JS di mymodule sia eseguito dopo il js di vertical_tab. Esiste un modo puramente basato su JavaScript per ponderare i comportamenti?
cam8001,

@ cam8001: lo so, ma ciò significherebbe che dovresti installare tutti i moduli, per conoscere il peso più leggero utilizzato da un modulo. La pagina che ho trovato elencava i pesi del modulo e potrebbe essere utile quando devi sapere quale peso devi assegnare al tuo modulo da eseguire prima di ogni modulo. Lo so, potresti semplicemente usare un peso estremamente leggero, ma useresti un peso più leggero del necessario.
kiamlaluno

@ cam8001: in tal caso, non c'è modo di realizzare ciò che si sta tentando di fare, se non quello di modificare l'ordine degli oggetti contenuti Drupal.behaviors; come ho riportato $.each(Drupal.behaviors)elenca gli oggetti nello stesso ordine in cui sono inseriti, non basandosi sul loro identificatore.
kiamlaluno

5

Utilizzare il modulo Pesi comportamentali .
(Si prega di fare alcuni test prima di utilizzarlo in un sito di produzione)

Il modulo consente di associare pesi ai comportamenti, quindi dirotta / sostituisce drupal.attachBehaviorscon un'implementazione personalizzata, che rispetta i pesi.


Perché non caricare il peso del modulo, come suggerito nell'altra risposta?

  • il peso del modulo è uno strumento piuttosto pesante. Si applica a tutte le implementazioni hook (php) e comportamenti (js) del modulo, mentre siamo interessati solo a un singolo comportamento.
  • l'ordine delle proprietà in un oggetto js non è garantito dalla specifica (sebbene sia implementato come ci si aspetterebbe in quasi tutti i browser).

Vedi
È prevedibile l'ordine dei campi in un oggetto javascript quando li si scorre in sequenza? e
Elements order - per il ciclo (... in ...) in javascript .


@kiam, Se trasformassi questo modulo in un "peso comportamentale" ("bewgt") su drupal.org, ti uniresti come co-manutentore? Probabilmente sarà un modulo piuttosto piccolo, ma probabilmente meglio di lasciarlo spedito con qualcos'altro. Ho un'implementazione di esempio localmente per D6, sembra funzionare.
donquixote,

appena fatto .. sei ancora invitato :)
donquixote,

drupal.org/node/1302126 - Spero che questo sia fondamentale in D8 :)
donquixote,

Sarebbe un modulo interessante, ma devo prima aggiornare il codice di alcuni dei miei moduli, per i quali non ho scritto una riga di codice da secoli. Dopo ciò, potrei essere libero per lo sviluppo congiunto di un nuovo modulo.
kiamlaluno

Sto solo dicendo che le persone chiedono casi d'uso. drupal.org/node/1302126#comment-5911632
donquixote,

0

Per Drupal 6 -

Una soluzione semplice, se non è necessario che sia portatile, è inserire il JS che si desidera eseguire per ultimo nel file template.php tema. Le chiamate a tema drupal_add_js sono sempre chiamate dopo i moduli.

Se deve essere portatile, la soluzione "più pulita" in drupal 6 è quella di aggiungere un nuovo modulo che abbia un peso diverso rispetto al modulo con il php. Potresti anche avere i due moduli nella stessa cartella, rendere il primo modulo dipendente dal primo e regolare i pesi negli hook di installazione / aggiornamento. Nessuno dei quali è necessario, semplifica l'installazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.