Wie kann ich die Reihenfolge von Drupal.behaviors steuern?

9

Ich möchte, dass der JavaScript-Code von Modul X erst ausgeführt wird, nachdem der von Modul Y ausgeführt wurde. Was ist der beste Weg, dies zu tun?

cam8001
quelle

Antworten:

5

Der von Drupal 7 verwendete JavaScript-Code lautet wie folgt:

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 verwendet einen ähnlichen Code:

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

Wenn JavaScript garantieren würde, dass Objekt- / Array-Eigenschaften immer in derselben Reihenfolge durchlaufen werden, in der sie hinzugefügt werden, werden die Werte in derselben Reihenfolge jQuery.each()an die Funktion übergeben, die als zweiter Parameter verwendet wird, in der sie in das als erster Parameter übergebene Array eingefügt werden.
Dies würde bedeuten, dass das erste eingefügte Verhalten Drupal.behaviorszuerst ausgeführt wird.
In diesem Fall können Sie ein geringeres Gewicht verwenden, damit die von Ihrem Modul definierten Verhaltensweisen zuerst ausgeführt werden können. Wenn Sie möchten, dass sie vor den anderen ausgeführt werden, sollte das Modulgewicht auf -50 eingestellt werden. andere Werte können auch funktionieren. Wenn Sie Drupal 7 verwenden, wird drupal_add_js ()Ermöglicht das Zuordnen einer Gewichtung zum JavaScript-Code. JavaScript-Code mit einem geringeren Gewicht wird zuerst in der HTML-Ausgabe angezeigt. Dies ist mit Drupal 6 nicht möglich.

JavaScript garantiert nicht, dass Eigenschaften in derselben Reihenfolge durchlaufen werden, in der sie hinzugefügt wurden. Dies bedeutet, dass verschiedene JavaScript-Implementierungen dieselben Eigenschaften in einer anderen Reihenfolge aufweisen. Dies bedeutet auch, dass sich dieselbe Reihenfolge in verschiedenen Versionen desselben Browsers ändern kann.

kiamlaluno
quelle
Ich habe einmal eine Seite gefunden, auf der das Gewicht einiger Module aufgeführt ist. Ich erinnere mich nicht an die URL dieser Seite und ob die Seite nur bestimmte Module enthielt oder erschöpfend war. Wenn ich diese Seite finde, werde ich hier den Link melden.
Kiamlaluno
1
Sie können immer einfach in der select name, weight from system where type = 'module' order by weight ASC, name
Systemtabelle
Leider muss das PHP (mymodule) meines Moduls vor dem PHP des anderen Moduls (vertikale_tabs) ausgeführt werden, aber das JS von mymodule muss nach dem js von vertical_tab ausgeführt werden. Gibt es eine rein auf Javascript basierende Methode, um Verhaltensweisen zu gewichten?
Cam8001
@ cam8001: Ich weiß das, aber das würde bedeuten, dass Sie alle Module installieren sollten, um das geringere Gewicht eines Moduls zu kennen. Auf der Seite, die ich gefunden habe, sind die Modulgewichte aufgeführt. Dies kann hilfreich sein, wenn Sie wissen müssen, welches Gewicht Sie Ihrem Modul zuweisen sollen, das vor jedem Modul ausgeführt werden soll. Ich weiß, Sie könnten einfach ein extrem leichtes Gewicht verwenden, aber Sie würden ein Gewicht verwenden, das leichter ist als es benötigt wird.
Kiamlaluno
@ cam8001: In diesem Fall gibt es keine Möglichkeit, das zu erreichen, was Sie versuchen, außer die Reihenfolge der darin enthaltenen Objekte zu ändern Drupal.behaviors. Wie ich berichtet habe, werden $.each(Drupal.behaviors)die Objekte in derselben Reihenfolge aufgelistet, in der sie eingefügt werden, ohne auf ihrer Kennung zu basieren.
Kiamlaluno
5

Verwenden Sie das Modul Verhaltensgewichte .
(Bitte testen Sie es, bevor Sie es auf einer Produktionsstätte verwenden.)

Das Modul ermöglicht das Anhängen von Gewichten an Verhaltensweisen und entführt / ersetzt es dann drupal.attachBehaviorsdurch eine benutzerdefinierte Implementierung, die die Gewichte berücksichtigt.


Warum nicht stattdessen das Modulgewicht, wie in der anderen Antwort vorgeschlagen?

  • Das Modulgewicht ist ein ziemlich schweres Werkzeug. Es gilt für alle Hook-Implementierungen (PHP) und Verhaltensweisen (js) des Moduls, während wir nur an einem einzigen Verhalten interessiert sind.
  • Die Reihenfolge der Eigenschaften in einem js-Objekt wird von der Spezifikation nicht garantiert (obwohl sie in fast allen Browsern wie erwartet implementiert ist).

Siehe
Ist die Reihenfolge der Felder in einem Javascript-Objekt beim Durchlaufen dieser Felder prädikatierbar? und
Elemente bestellen - for (… in…) Schleife in Javascript .

Donquijote
quelle
@kiam, Wenn ich dies zu einem Modul "Verhaltensgewicht" ("bewgt") auf drupal.org mache, würden Sie als Co-Betreuer beitreten? Es wird wahrscheinlich ein ziemlich kleines Modul sein, aber wahrscheinlich besser, als es mit etwas anderem ausliefern zu lassen. Ich habe eine Beispielimplementierung lokal für D6, scheint zu funktionieren.
Donquijote
habe es gerade geschafft .. du bist immer noch eingeladen :)
donquixote
drupal.org/node/1302126 - Ich hoffe, dass dies im Kern in D8 sein wird :)
Donquixote
Es wäre ein interessantes Modul, aber ich muss zuerst den Code einiger meiner Module aktualisieren, für die ich seit Ewigkeiten keine Codezeile mehr geschrieben habe. Danach konnte ich ein neues Modul mitentwickeln.
Kiamlaluno
Nur zu sagen, die Leute fragen nach Anwendungsfällen. drupal.org/node/1302126#comment-5911632
Donquixote
0

Für Drupal 6 -

Eine einfache Lösung, wenn dies nicht portabel sein muss, besteht darin, das JS, das Sie zuletzt ausführen möchten, in die Datei theme template.php einzufügen. Die Aufrufe des Themas drupal_add_js werden immer nach Modulen aufgerufen.

Wenn es portabel sein muss, besteht die "sauberste" Lösung in Drupal 6 darin, ein neues Modul hinzuzufügen, das ein anderes Gewicht hat als Ihr Modul mit dem PHP. Sie können sogar die beiden Module im selben Ordner haben, das erste Modul vom ersten abhängig machen und die Gewichte in den Installations- / Update-Hooks anpassen. Nichts davon ist notwendig, erleichtert nur die Installation.

mirzu
quelle