Bagaimana saya bisa mengontrol urutan perilaku Drupal.


9

Saya ingin kode JavaScript dari modul X hanya berjalan setelah kode dari modul Y dijalankan. Apa cara terbaik untuk melakukan ini?

Jawaban:


5

Kode JavaScript yang digunakan oleh Drupal 7 adalah sebagai berikut:

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 menggunakan kode serupa:

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

Jika JavaScript akan menjamin bahwa properti objek / array selalu dilalui dalam urutan yang sama dengan yang ditambahkan, maka nilai akan diteruskan dari jQuery.each()ke fungsi yang digunakan sebagai parameter kedua dalam urutan yang sama dengan yang dimasukkan ke dalam array yang dilewatkan sebagai parameter pertama.
Ini berarti bahwa perilaku pertama yang dimasukkan Drupal.behaviorsdijalankan terlebih dahulu.
Dalam hal ini, untuk memungkinkan perilaku yang didefinisikan oleh modul Anda dijalankan terlebih dahulu, Anda bisa menggunakan bobot yang lebih ringan untuknya. Jika Anda ingin mereka dieksekusi sebelum yang lain, bobot modul harus diatur ke -50; nilai-nilai lain juga bisa berfungsi. Jika Anda menggunakan Drupal 7, drupal_add_js ()memungkinkan untuk mengaitkan bobot dengan kode JavaScript; Kode JavaScript dengan bobot yang lebih ringan muncul pertama kali dalam output HTML. Ini tidak mungkin dengan Drupal 6, pikir.

JavaScript tidak menjamin bahwa properti dilalui dalam urutan yang sama seperti yang ditambahkan. Ini berarti bahwa implementasi JavaScript yang berbeda akan menyajikan properti yang sama menggunakan urutan yang berbeda; itu juga berarti bahwa urutan yang sama dapat berubah di berbagai versi browser yang sama.


Saya pernah menemukan halaman yang memuat daftar bobot yang digunakan oleh beberapa modul. Saya tidak ingat URL halaman itu, dan jika halaman hanya menyertakan modul tertentu, atau itu lengkap. Jika saya menemukan halaman itu, saya akan melaporkan di sini tautannya.
kiamlaluno

1
Anda selalu dapat memeriksa di tabel sistem - cobaselect name, weight from system where type = 'module' order by weight ASC, name
cam8001

Sayangnya saya membutuhkan modul PHP (mymodule) untuk dijalankan sebelum modul lain (vertical_tab) PHP, tetapi mymodule's JS dijalankan setelah js vertical_tab. Apakah ada cara javascript murni untuk perilaku berat badan?
cam8001

@ cam8001: Saya tahu itu, tetapi itu berarti Anda harus menginstal semua modul, untuk mengetahui bobot yang lebih ringan yang digunakan oleh sebuah modul. Halaman yang saya temukan mencantumkan bobot modul, dan ini bisa berguna ketika Anda perlu tahu bobot apa yang harus Anda tetapkan untuk modul Anda yang akan dieksekusi sebelum setiap modul. Saya tahu, Anda hanya bisa menggunakan bobot yang sangat ringan, tetapi Anda akan menggunakan bobot yang lebih ringan daripada yang dibutuhkan.
kiamlaluno

@ cam8001: Dalam hal ini, tidak ada cara untuk mencapai apa yang Anda coba lakukan, kecuali mengubah urutan objek yang terkandung di dalamnya Drupal.behaviors; ketika saya melaporkan $.each(Drupal.behaviors)daftar objek dalam urutan yang sama mereka dimasukkan, bukan berdasarkan pengenal mereka.
kiamlaluno

5

Gunakan modul Berat Perilaku .
(Tolong beri beberapa pengujian sebelum Anda menggunakannya di situs produksi)

Modul ini memungkinkan untuk melampirkan bobot pada perilaku, dan kemudian membajak / menggantikan drupal.attachBehaviorsdengan implementasi kustom, yang benar-benar menghormati bobot.


Mengapa bukan bobot modul, seperti yang disarankan dalam jawaban lain?

  • Berat modul adalah alat yang cukup berat. Ini berlaku untuk semua implementasi hook (php) dan perilaku (js) dari modul, sementara kami hanya tertarik pada satu perilaku tunggal.
  • urutan properti di objek js tidak dijamin oleh spec (meskipun diimplementasikan seperti yang Anda harapkan di hampir semua browser).

Lihat
Apakah urutan bidang dalam objek javascript tidak dapat diprediksi saat melakukan perulangan? dan
Elemen pesanan - untuk (... dalam ...) loop dalam javascript .


@kiam, Jika saya menjadikan ini modul "behaviour weight" ("bewgt") di drupal.org, maukah Anda bergabung sebagai co-maintainer? Ini mungkin akan menjadi modul yang cukup kecil, tetapi mungkin lebih baik daripada membiarkannya dikirim dengan sesuatu yang lain. Saya punya implementasi sampel secara lokal untuk D6, tampaknya berhasil.
donquixote

baru saja selesai .. Anda masih diundang :)
donquixote

drupal.org/node/1302126 - Saya harap ini akan menjadi inti di D8 :)
donquixote

Ini akan menjadi modul yang menarik, tetapi saya harus terlebih dahulu memperbarui kode beberapa modul saya, di mana saya tidak menulis garis kode sejak lama. Setelah itu, saya bisa bebas untuk mengembangkan modul baru.
kiamlaluno

Hanya mengatakan, orang-orang meminta kasus penggunaan. drupal.org/node/1302126#comment-5911632
donquixote

0

Untuk Drupal 6 -

Solusi sederhana, jika ini tidak perlu portabel adalah dengan meletakkan JS yang ingin Anda jalankan terakhir ke file theme templat.php. Panggilan tema drupal_add_js selalu dipanggil setelah modul.

Jika memang perlu portable, solusi "terbersih" di drupal 6 adalah menambahkan modul baru yang memiliki bobot berbeda dari modul Anda dengan php. Anda bahkan dapat memiliki dua modul di folder yang sama, membuat modul pertama bergantung pada yang pertama, dan menyesuaikan bobot dalam kait instal / perbarui. Tidak ada yang diperlukan, hanya membuat instalasi lebih mudah.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.