pilih jQuery tidak berfungsi di Meteor 1.1.0.2 diRendered

Saya sedang mengerjakan aplikasi yang telah saya terapkan, dan mencoba memperbarui semuanya ke versi terbaru dan memperbarui kode untuk memanfaatkan proses terbaru, seperti berlangganan Template.onRendered, tetapi tampaknya penyortiran saya rusak.

Templat saya (agak disederhanakan)

<template name="formEdit">
  <div id="formContainer">
    {{#if Template.subscriptionsReady}}
      {{#with form this}}
        <table id="headerFieldsTable" class="table">
          <tbody id="headerFields">
            {{#each headerFields}}
              <tr class="headerFieldRow">
                <td>{{> headerFieldViewRow }}</td>
              </tr>
            {{/each}}
          </tbody>
        </table>

        <h5>Form Fields</h5>
        <table id="formFieldsTable" class="table">
          <tbody id="formFields">
            {{#each formFields}}
              <tr class="formFieldRow">
                <td>{{> formFieldViewRow }}</td>
              </tr>
            {{/each}}
          </tbody>
        </table>

      {{/with}}
    {{else}}
      Loading...
    {{/if}}
  </div>
</template>

Dan templatnya onRendered():

Template.formEdit.onRendered(function() {
  var formsSubscription = this.subscribe('formById', this.data);
  var headerFieldsSubscription = this.subscribe('headerFieldsForForm', this.data);
  var formFieldsSubscription = this.subscribe('formFieldsForForm', this.data);

  var formEditTemplate = this;
  this.autorun(function() {
    if (formsSubscription.ready() && headerFieldsSubscription.ready() && formFieldsSubscription.ready()) {
formEditTemplate.$(''));
      formEditTemplate.$('#headerFields').sortable({
        axis: "y",
        stop: function(event, ui) {
          var headersToSave = [];
          $('#headerFieldsTable div.headerField').each(function(idx, headerFieldDiv) {
            var header = Blaze.getData(headerFieldDiv);
            header.sequence = idx;
            headersToSave.push(header);
          });
          _.each(headersToSave, function(header) { header.save(); });
        }
      });

      formEditTemplate.$('#formFields').sortable({
        axis: "y",
        stop: function(event, ui) {
          var feildsToSave = [];
          $('#formFieldsTable div.formField').each(function(idx, formFieldDiv) {
            var field = Blaze.getData(formFieldDiv);
            field.sequence = idx;
            feildsToSave.push(field);
          });
          _.each(feildsToSave, function(field) { field.save(); });
        }
      });
    }
  });
});

Namun untuk header dan footer, formEditTemplate.$('#headerFields') dan formEditTemplate.$('#formFields') keduanya sepertinya tidak memberikan hasil. Sepertinya DOM sebenarnya tidak ada. Saya pikir panggilan .ready() pada semua langganan akan memperbaikinya, tetapi menurut saya ada masalah waktu ketika Blaze belum memperbaiki DOM, tetapi langganan sudah selesai. Saya mengatakan ini karena saya meletakkan breakpoint di Chrome tepat di baris pertama if, dan browser masih menampilkan "Memuat...".

Saya juga mencoba melakukan hot-wire dengan meminta bantuan yang menyiapkan pengurutan ditempatkan di akhir blok {{#with}}, berharap mungkin itu akan dirender terakhir, tetapi itu juga tidak berhasil.

Saya menemukan beberapa artikel di forum Meteor yang sepertinya menyarankan penambahan pengatur waktu, tetapi ini tampaknya sangat "retas". Apakah ada pola baru untuk menjalankan JS yang mengharuskan DOM diinisialisasi sepenuhnya?


person CodeChimp    schedule 26.07.2015    source sumber


Jawaban (1)


Daripada melakukan peretasan penundaan waktu, saya sarankan Anda menggunakan Tracker.afterFlush() untuk menjamin bahwa DOM telah dibuat dan diperbarui. Berikut ini deskripsi dari Dokumen Meteor:

Menjadwalkan suatu fungsi untuk dipanggil pada flush berikutnya, atau nanti pada flush saat ini jika ada yang sedang berlangsung, setelah semua perhitungan yang tidak valid dijalankan kembali. Fungsi ini akan dijalankan sekali dan tidak pada flush berikutnya kecuali afterFlush dipanggil lagi.

Jadi di dalam pernyataan if Anda, Anda dapat membungkus blok kode seperti itu

if (formsSubscription.ready() && headerFieldsSubscription.ready() && formFieldsSubscription.ready()) {
  Tracker.afterFlush( function () {
    //Code block to be executed after subscriptions ready AND DOM updated
  });
}

Berikut adalah referensi dengan contoh menggunakan Tracker.afterFlush.

person FullStack    schedule 27.07.2015
comment
Entah kenapa saya selalu lupa Tracker.afterFlush() ada. Terima kasih, ini bekerja dengan sempurna. - person CodeChimp; 28.07.2015