Ember.js: [Glimmer 2] "Mundur re-render" sekarang menjadi pernyataan

Dibuat pada 29 Jul 2016  ·  63Komentar  ·  Sumber: emberjs/ember.js

Backtracking re-render mengacu pada skenario di mana, di tengah proses rendering, Anda telah memodifikasi sesuatu yang telah dirender.

Sebagai contoh:

{{foo}} {{foo-bar parent=this}}
// app/components/foo-bar.js

export default Ember.Component.extend({
  init() {
    this._super(...arguments);
    this.get('parent').set('foo', 'bar');
  }  
});

Seperti yang Anda lihat, pada saat komponen foo-bar dipakai dan dirender, kita telah menggunakan nilai foo dari konteks induk untuk mengisi keriting {{foo}} . Namun, dalam konstruktornya, ia mencoba mengubah nilai yang sama, karenanya. "mundur".

Ini adalah contoh yang cukup ekstrim, tetapi menggambarkan masalahnya. Selain init , didInitAttrs , didReceiveAttrs , willInsertElement dan willRender juga terjadi secara serempak selama proses rendering. Selain itu, backtracking sering menjadi masalah yang timbul dari perilaku properti terikat dua arah.

Perilaku ini selalu tidak dapat diandalkan, tetapi sebagian didukung dengan penghentian (sejak Ember 1.13):

You modified ApplicationController.foo twice in a single render. This was unreliable in Ember 1.x and will be removed in Ember 3.0

Sejak 1.13, Ember mendukung hal ini dengan segera melakukan rendering ulang kedua saat pelacakan mundur terdeteksi (dan kemudian mengulanginya hingga sistem stabil). Strategi ini sendiri bisa menjadi sumber masalah kinerja. Dalam kasus ekstrim, ini bisa menyebabkan infinite loop.

Di Glimmer 2, sementara rendering ulang ekstra relatif murah, pembukuan ekstra untuk mendeteksi set mundur tidak. Salah satu keunggulan sistem Glimmer 2 adalah ia tidak perlu menyiapkan pengamat untuk melacak perubahan. Lebih lanjut, pengoptimalan tertentu di Glimmer 2 memungkinkan sistem untuk melewati subpohon yang melintasi ketika tidak ada yang berubah di dalamnya.

Bersama-sama, faktor-faktor ini berarti bahwa kita tidak dapat dengan mudah mendeteksi set s backtracking ini (atau apakah ada sesuatu yang "sudah dirender" atau tidak) tanpa melakukan pembukuan ekstra dalam jumlah besar dan dengan sengaja menggagalkan pengoptimalan ini.

Kami telah menulis kode untuk mendukung ini, tetapi karena sifat fitur yang sudah tidak dapat diandalkan, dan biaya pembukuan (sangat signifikan), kami ragu untuk mengaktifkannya secara otomatis untuk semua orang tanpa mengetahui apakah itu masih diperlukan.

Sebagai kompromi, saat ini kami hanya melakukan deteksi dalam mode pengembangan dan mengubah pesan penghentian menjadi pernyataan mode pengembangan (kesalahan keras). Dalam mode produksi, kode deteksi dilucuti dan pelacakan mundur tidak akan berfungsi.

Kami telah menyimpan fasilitas untuk mendukung fitur ini (tanpa pernyataan) di basis kode di belakang tanda fitur kedua. Kode sedang diuji terus-menerus pada CI, namun dinonaktifkan secara default hingga kami memiliki informasi penggunaan yang cukup untuk menentukan langkah selanjutnya.

Jika Anda yakin bahwa Anda memiliki pola penggunaan yang terpengaruh oleh hal ini, berikan detail sebanyak mungkin tentang skenario Anda di bawah ini. Sangat mungkin bahwa ada alternatif dan/atau solusi yang ditargetkan yang dapat kita gunakan yang tidak memerlukan perubahan besar-besaran pada mesin. Oleh karena itu, akan sangat membantu jika Anda memberikan informasi latar belakang dan konteks tentang penggunaan Anda alih-alih hanya menunjukkan kepada kami cuplikan kode kecil dari basis kode Anda.

Ember 2.10 Inactive

Komentar yang paling membantu

Ini tidak disebutkan dalam posting blog 2.10 dan mengejutkan saya karena peringatan penghentian sebelumnya mengatakan akan didukung hingga 3.0, seperti yang disebutkan di atas.

Semua 63 komentar

FYI, kami memiliki beberapa peringatan ini di aplikasi kami. Secara khusus, kami memperbarui beberapa properti layanan di init komponen, yang akan memicu sesuatu yang lain di halaman untuk dirender secara berbeda.

Sangat mudah untuk memperbaiki peringatan ini dengan menjadwalkan perubahan properti pada run loop berikutnya. Butuh waktu ~ satu jam untuk melacak dan memperbaiki semua peringatan di aplikasi kami (yang cukup besar). Meskipun ini secara teknis merupakan perubahan yang melanggar, saya setuju dengan penilaian Anda meskipun itu membuat saya bekerja ekstra.

@fivetanley meningkatkan pesan kesalahan di sini terdengar bagus. Saya tahu @krisselden dan @stefanpenner memiliki alur kerja untuk melacak masalah ini, mungkin mereka dapat membantu memberi Anda beberapa petunjuk tentang ini.

@joukevandermaas run.next() bukan perbaikan yang bagus untuk kesalahan ini, meskipun saya mengerti jika Anda kewalahan dengan kesalahan ini mengapa Anda pergi ke sana. Yang terbaik adalah mencoba memahami mengapa aliran balik data membatalkan hal-hal yang sudah dirender.

Kemungkinan jika Anda menyetel props pada layanan yang dapat disuntikkan ke komponen apa pun, itu meningkatkan kemungkinan set itu membatalkan sesuatu yang sudah dirender. Secara umum, polanya harus set() hanya digunakan pada status internal selama rendering kait, tidak terikat pada input atau layanan dan atau set() digunakan pada suatu peristiwa, status input harus diselesaikan pada saat hal-hal dirender.

@joukevandermas run.next() bukan perbaikan yang bagus untuk kesalahan ini,

melakukannya menyebabkan masalah kinerja, karena glimmer2 dalam hal ini menginformasikan "pekerjaan duplikat sedang terjadi, Anda benar-benar tidak menginginkan ini jika Anda menginginkan aplikasi berkinerja". Di mana sebelumnya, bara akan menyerap ini, tetapi menghasilkan penalti kinerja yang berat.

Kami memiliki lebih banyak pekerjaan berbagi pengetahuan yang harus dilakukan di sini... Pada akhirnya kami percaya ini adalah jalan yang sehat ke depan untuk aplikasi. Tetapi kita perlu memastikan setiap orang memiliki alat + pengetahuan yang tersedia untuk mendapatkan manfaat :)

Sebagai orang yang mengikuti kejadian Ember secara relatif dekat (twitter, di sini di github, milis, dll) masalah ini menyelinap pada saya jadi saya akan curiga bahwa ini mungkin mengejutkan orang lain jika masuk sebagai bagian dari Ember 2.10, terutama karena peringatan penghentian yang terkait dengannya secara khusus menyatakan perilaku akan didukung hingga 3.0. Saya tidak percaya saya pernah melihatnya disosialisasikan di mana pun bahwa perilaku ini tidak akan berhasil di Glimmer 2 (walaupun saya mungkin melewatkannya begitu saja).

curiga bahwa ini mungkin mengejutkan orang lain jika mendarat sebagai bagian dari Ember 2.10, terutama karena peringatan penghentian yang terkait dengannya secara khusus menyatakan perilaku akan didukung hingga 3.0. Saya tidak percaya saya pernah melihatnya disosialisasikan di mana pun bahwa perilaku ini tidak akan berhasil di Glimmer 2 (walaupun saya mungkin melewatkannya begitu saja).

yup, kami perlu meningkatkan beberapa perpesanan / detail di sini.

Saya melihat ini berhasil masuk ke rilis 2.10. Apakah ini akan disebutkan dalam posting blog rilis 2.10?

Ini tidak disebutkan dalam posting blog 2.10 dan mengejutkan saya karena peringatan penghentian sebelumnya mengatakan akan didukung hingga 3.0, seperti yang disebutkan di atas.

Saya memiliki pola penggunaan yang terpengaruh oleh ini. Saya yakin masalahnya pasti pola penggunaan saya, dan bukan perubahan khusus ini, tetapi saya ingin beberapa masukan tentang pola penggunaan alternatif yang baik!

Pada dasarnya, saya memiliki halaman yang menunjukkan kumpulan data yang dapat difilter, dan untuk mencapai ini, saya menggunakan nilai yang dihitung Ember untuk memfilter data berdasarkan nilai beberapa parameter kueri pada halaman. Namun, untuk mencegah input yang tidak valid (misalnya bukan huruf atau angka) ditambahkan ke parameter kueri dari input pengguna, saya memiliki pola berikut:

 filteredModel: Ember.computed('model', /*list of individual query params*/, function(){
    let model = this.get('model').filterBy('pdf.pdf_path.url'); //removes all records that don't have a pdf uploaded
    this.get('queryParams').forEach((filter)=> { // for each possible filter
      if ((this.get(filter).length > 0)) { //if the filter has content...
        //guardian pattern to prevent invalid inputs
        let valid = new RegExp('^[A-Za-z0-9 _]*[A-Za-z0-9][A-Za-z0-9 _]*$');
        while (this.get(filter).length > 0 && !valid.test(this.get(filter))){
          this.set(filter, this.get(filter).slice(0,-1));
        }
        //block of code where the model gets filtered
        //...
        //...
    });
    return model;
  }),

Jadi pada dasarnya, ketika saya menghitung seperti apa model yang difilter, jika salah satu nilai filter memiliki karakter yang tidak valid di dalamnya, saya menghapus karakter terakhir hingga menjadi valid. Adakah yang punya saran cara yang lebih bersih untuk melakukan pemeriksaan validitas pada input ini?

Ini mengejutkan kami juga - terutama karena kami tidak melihat pesan peringatan apa pun saat aplikasi berjalan dengan 2.9. Saat kami meningkatkan ke 2.10 aplikasi tidak akan memuat dan merujuk kesalahan ini. Apakah ada orang lain yang melihat perilaku ini?

@revanar Saya bisa benar-benar mati di sini, tetapi sepertinya CP Anda sebenarnya adalah dua hal yang berbeda: satu CP untuk mengembalikan model yang difilter dan satu untuk memperbarui filter. Saya akan memindahkan bagian pembaruan filter menjadi yang dapat diamati. Atau, jika ini adalah komponen dan Anda meneruskan parameter kueri ke dalam komponen, saya akan memindahkan logika ke dalam kait didReceiveAttrs . Dari pengalaman saya mengalami kesalahan "backtracking rerender", saya pikir memindahkan operasi set dari CP akan membuat kesalahan hilang.

Kami mengalami waktu yang sulit dengan ini juga. Saya telah memperbaiki banyak masalah, tetapi satu contoh yang kami lihat dari kesalahan penghentian ini membingungkan.

Assertion Failed: You modified transitioningIn twice on <app<strong i="6">@component</strong>:link-to::ember1159> in a single render.

Sepertinya kegagalan terjadi karena properti internal ember diperbarui lebih dari sekali. Sayangnya itu mereproduksi selama pengujian Selenium kami sehingga sulit untuk di-debug (driver Selenium mencegah alat dev bekerja saat pengujian berjalan). Saya melacak setidaknya satu contoh masalah ke panggilan controller.transitionToRoute yang dibuat di akhir proses masuk kami, tetapi tampaknya terjadi dalam beberapa skenario yang berbeda.

Saya tidak yakin bagaimana melanjutkan pemecahan masalah ini.

@chancancode menyebutkan tanda fitur untuk menonaktifkan kesalahan penghentian ini, tetapi saya tidak melihat info tentangnya di https://github.com/emberjs/ember.js/blob/master/FEATURES.md. Ada yang tahu apa itu bendera?

Untuk migrasi ember 2.10 kami juga, ini adalah titik nyeri utama. Kami juga telah memperbaiki banyak masalah ini. Tampaknya tidak ada strategi tunggal/jelas untuk memperbaiki kesalahan ini. Kami telah mencoba pendekatan berikut, tergantung pada kasus penggunaan

  1. Membungkus kode dalam Ember.run.next
  2. Memindahkan kode setter dari computed properties ke kait siklus hidup, atau ke event handlers , jika memungkinkan.
  3. Mencoba berbagai kombinasi kait siklus hidup untuk komponen

Kami juga mengalami banyak kesulitan dalam hal ini. Selama beberapa tahun terakhir kami telah mengumpulkan cukup banyak drop down yang secara otomatis memilih elemen pertama dari jenis tertentu dari cache penyimpanan data ember. Ini menyebabkan rendering ulang karena beberapa bagian halaman didorong oleh pilihan dropdown. Saya tidak yakin apa yang harus dilakukan karena saya tidak ingin mengulangi kode yang sama untuk mengisi dan memilih item pertama dari daftar di setiap halaman tempat dropdown digunakan.

@scottmessinger Terima kasih atas umpan baliknya. Menggunakan komponen akhirnya bekerja dengan cukup baik. Saya telah berhasil menghilangkan kesalahan lacak balik, dan saya pikir kode saya sedikit lebih bersih untuk itu.

Kris Selden memiliki tip berguna untuk men-debug ini:

screen shot 2016-12-12 at 13 10 44

Saya telah menguraikan langkah-langkah lebih detail di sini: https://github.com/GavinJoyce/backtracking/pull/1#issuecomment -266427152

Saya sedang berupaya meningkatkan pesan pernyataan mundur . Saya telah memotong build 2.10.2-with-improved-backtracking-assertion yang menyertakan pesan-pesan yang lebih baik ini:

Sebelum:

Anda memodifikasi message.message_goal.description dua kali pada <(subclass of Ember.Model):ember3486> dalam satu render. Ini tidak dapat diandalkan dan lambat di Ember 1.x dan tidak lagi didukung. Lihat https://github.com/emberjs/ember.js/issues/13948 untuk detail lebih lanjut.

Setelah:

Anda memodifikasi message.message_goal.description dua kali pada <(subclass of Ember.Model):ember3486> dalam satu render. Itu dirender dalam component:message-edit-expanding-container-component dan dimodifikasi dalam component:rules/predicate-date-value-component . Ini tidak dapat diandalkan dan lambat di Ember 1.x dan tidak lagi didukung. Lihat #13948 untuk lebih jelasnya.

Saya memiliki beberapa hal lagi yang harus dilakukan sebelum siap, tetapi akan sangat berguna jika beberapa orang mencobanya di aplikasi mereka. /cc @fivetanley , @bryanhickerson , @revanar , @phammers , @scottmessinger , @tharington1 , @manimis902 , @jakesjews , @elwayman02. Beri tahu saya jika Anda melihat pesan pernyataan yang tidak ideal di aplikasi Anda.

Untuk mencobanya, perbarui bower.json untuk menyertakan dependensi bara sebagai berikut:

{
  "name": "backtracking",
  "dependencies": {
    "ember": "intercom/ember#2.10.2-with-improved-backtracking-assertion",
    "ember-cli-shims": "0.1.3"
  },
  "resolutions": {
    "ember": "2.10.2-with-improved-backtracking-assertion"
  }
}

Anda dapat melihat contoh aplikasi yang menjalankan build ini di sini: https://github.com/GavinJoyce/backtracking/pull/10

Saya baru saja memotong build 1.11.0-canary

Apakah ini salah ketik?

@rwjblue terima kasih, ini salah ketik. Diperbarui

@GavinJoyce terima kasih telah menerima ini! Saya mencoba ini di aplikasi kami dan itu pasti _lebih_ membantu daripada pesan sebelumnya. Sayangnya bagi kami itu masih tidak membuatnya sangat mudah untuk memperbaiki masalah ini karena properti yang dicatatnya telah dimodifikasi tidak dimodifikasi secara jelas di kedua lokasi yang ditunjukkan oleh pesan kesalahan. Saya tidak begitu yakin mengapa itu terjadi, tetapi kami berharap untuk menggali lebih dalam tahun depan.

@Dhaulagiri jika Anda tertarik, saya akan senang untuk mengatur

FWIW Saya telah menemukan masalah lain yang terkait dengan ini: https://github.com/alexspeller/ember-cli-active-link-wrapper/issues/25

Juga mencoba cabang oleh @GavinJoyce ketika mencoba menemukan bug dalam upaya berkelanjutan untuk membawa kontrol tab ke kertas ember (PR referensi di atas). Sayangnya sepertinya dalam kasus saya, saya juga mendapatkan referensi ke komponen yang tampaknya tidak terlibat.

@bjornharrtell apakah Anda memiliki cabang kertas bara yang bisa saya coba?

^ Kami mengambil sedikit waktu untuk menyelami masalah kertas bara (https://github.com/miguelcobain/ember-paper/pull/590). Tampaknya:

  • pesan kesalahan baru lebih berguna daripada yang sekarang
  • mereka tidak sempurna karena mereka tidak menangani konten yang dihasilkan dengan baik. (komponen yang berisi {{yield}} dilaporkan sebagai sumber yang berguna, tetapi tidak berguna seperti yang seharusnya)

Ini mungkin atau mungkin bukan bug dengan addon, tetapi saya menemukan kesalahan ini di https://github.com/DockYard/ember-one-way-controls/issues/136

Saya telah menemukan masalah.
Saya menggunakan mixin yang memiliki titik masuk untuk memperbarui properti yang sama untuk pengontrol yang dicampur. Ini jelas merupakan properti yang berbeda karena mereka hanya milik pengontrol yang berbeda dan pernyataan gagal dan memblokir js.
Saya telah menguji mixin dengan membukanya ke beberapa pengontrol dan membuat transisi antara rute untuk mereproduksi - itu tidak direproduksi.

Untuk saat ini saya mencoba untuk menyingkirkan mixin jadi saya akan membunuhnya dan akan membuat solusi.

Saya yakin saya memiliki kasus penggunaan yang valid di mana kami melihat masalah rendering ulang ini. Di aplikasi kami, kami memiliki tombol yang berisi beberapa status (ok, validasi, peringatan, kesalahan). Ini adalah komponen yang menunjukkan keadaan saat ini, memvalidasi ketika hal-hal tertentu terjadi, dan berdasarkan hasil validasi atau aktivasi, menampilkan hal-hal yang berbeda (pemintal, teks tombol yang berbeda, kelas tombol yang berbeda).

Kami memeriksa validasi pada init() dan berdasarkan respons validasi, atur status tombol yang sesuai. Kelas tombol adalah properti yang dihitung yang menetapkan kelas yang sesuai berdasarkan status tombol. Karena itu terjadi pada init, sepertinya kesalahan ini dipicu karena kita memulai dengan status ok pada instantiasi, kemudian beralih ke validasi saat kita memvalidasi versi dan status akhir berdasarkan respons. Namun, use case itu sendiri tampaknya masuk akal dan oleh karena itu perubahan keadaan yang terjadi juga tampak masuk akal.

@tundal45 mungkinkah Anda dapat membuat aplikasi twiddle atau sampel yang menunjukkan apa yang Anda yakini sebagai kesalahan yang salah?

@Blackening999 @tundal45 dapatkah Anda mengurangi usecase Anda menjadi twiddle?

@chancancode @Blackening999 Saya akan mencoba mempostingnya di sini segera. Terima kasih atas respon yang cepat.

@chancancode https://ember-twiddle.com/936d549b5625b0cf4f3c945d0ed04d3b?openFiles=components.button-with-state.js akan menjadi twiddle tetapi saya tidak melihat kesalahan yang saya lihat di aplikasi jadi mungkin ada hal lain yang menyebabkannya.

Saya melihat ini di beberapa properti yang dihitung, salah satunya adalah Ember.computed.or . Karena tidak ada saran @ manimis902 yang berlaku dalam kasus ini, apa solusi yang tepat?

Seperti @tharington1 sebutkan di mana bendera untuk fitur yang disebutkan oleh @chancancode ?

@cbou sejauh yang saya tahu bahwa bendera tidak ada

Saya tidak sepenuhnya yakin bagaimana menangani pemberitahuan penghentian ini, saya juga tidak yakin apakah perbaikan saya valid/valid, tetapi saya melakukan permintaan AJAX di pengait komponen init() yang memicu perubahan nilai dalam yang berbeda properti layanan (untuk melacak/menampilkan jika mengakses server jarak jauh).

Saya memindahkan kode permintaan AJAX saya dari kait komponen init() ke kait komponen didRender() dan tampaknya telah menyelesaikan pemberitahuan penghentian saya.

@ lvl99 saya melakukan hal yang sama.

Kami berusaha keras untuk meningkatkan proyek perusahaan kami ke Ember 2.12 dari 2.3. Di proyek kami, kami memiliki add-on validasi dan add-on komponen formulir terpisah. Add-on validasi berfungsi di Ember.components untuk menghasilkan kesalahan validasi dan add-on komponen formulir menampilkan kesalahan yang dihasilkan oleh add-on validasi melalui helper. Pengaya terlalu rumit untuk berbagi kode sumber; maka kami membuat twiddle berikut untuk menggambarkan kasus yang kami hadapi.

Contoh yang diberikan berisi dua komponen ( person-detail dan address-detail ) yang bertanggung jawab untuk menghasilkan kesalahan validasi mereka sendiri. Kesalahan validasi yang dihasilkan oleh address-detail diturunkan ke komponen yang mengandung ( person-detail ) melalui tindakan yang dilemparkan dalam errors properti yang dihitung. Kesalahan yang dihasilkan oleh setiap komponen ditampilkan dalam komponen error-displayer dengan bantuan helper error-formatter . Kode yang diberikan berfungsi seperti yang Anda lihat.

Namun; kami memiliki peringatan penghentian sebagai berikut: DEPRECATION: The error property ofis an Ember.Binding connected to validatable.errors.name , but Ember.Binding is deprecated. Consider using an alias computed property instead. [deprecation id: ember-metal.binding] See http://emberjs.com/deprecations/v2.x#toc_ember-binding for more details. Untuk menghindarinya; silakan masuk ke helper error-formatter dan beri komentar pada baris nomor 9 dan batalkan komentar nomor baris 8 sehingga kami melakukan seperti yang disarankan dalam penjelasan peringatan.

Sekarang kita mencapai Assertion Failed: You modified "error" twice on <Ember.Object:ember338> in a single render. It was rendered in "component:error-displayer" and modified in "component:error-displayer". This was unreliable and slow in Ember 1.x and is no longer supported. See https://github.com/emberjs/ember.js/issues/13948 for more details. Kami mengerti mengapa kami mendapatkan kesalahan ini; karena tindakan memicu dalam address-detail s errors properti yang dihitung menghasilkan perhitungan ulang dari errors properti yang dihitung dari person-detail dan konten yang sudah dirender menyebabkan kesalahan ini . Inilah yang ingin kami pelajari:

  1. Ember.Binding vs Ember.computed.alias bekerja dengan cara yang sangat berbeda dalam hal fase kalkulasi ulang (re-rendering). Apa perbedaan tepatnya? Menyarankan menggunakan yang terakhir sebagai pengganti yang pertama tampaknya melanggar kode; setidaknya untuk kasus kami.
  2. Apakah memicu tindakan dari dalam properti yang dihitung merupakan masalah? Jika ya; apa saran yang mungkin untuk menghindarinya?
  3. Kami sedang mempertimbangkan untuk membungkus pemicu tindakan dengan pernyataan Ember.run.scheduleOnce('afterRender', ...) . Apakah ini cara yang benar?
  4. Akhirnya; silakan kembali ke sekarang melanggar kode dan ketik sesuatu ke bidang apa pun; dan secara mengejutkan komponen dirender ulang beberapa kali; kami menduga ini mungkin terkait dengan bug.

FWIW, saya telah melihat komponen saya dirender ulang lebih sering daripada yang saya harapkan dalam beberapa kasus. Melacak penyebab rerender cukup memakan waktu karena sering disinkronkan dengan runloop. Saya ingin tahu apakah ada jalan pintas atau trik debugging di area ini.

Apakah ada cara untuk menangkap atau menekan pernyataan ini pada build debug? Kami telah melacak dan memperbaikinya melalui refactors seperti yang dijelaskan di atas di sebagian besar tempat, tetapi ada 1 atau 2 yang agak keras kepala. Dalam satu kasus tertentu, kita menghancurkan sebuah objek, lalu bertransisi. Objek yang dihancurkan (di API kami) mengirimkan pemberitahuan pendorong untuk membongkar/menghancurkan beberapa objek lagi.

Dalam pembuatan produksi, rendering ulang tidak menjadi masalah, karena kami hanya menghancurkan objek, lalu beralih lagi (jadi seluruh rute sedang dirobohkan). Namun, pernyataan pada dev build cukup membuat frustrasi karena memerlukan penyegaran untuk memulihkan situs. Saya mengerti mengapa kami mendapatkan kesalahan, tetapi ini adalah refactor yang cukup rumit dalam hal ini untuk menghindarinya, dan dalam hal apa pun itu tidak masalah karena seluruh rute sedang dihancurkan. Apakah ada cara untuk menangkap/menekan/mengubah ini menjadi peringatan? Saya mencoba mencoba/menangkap, serta penangan kesalahan rute, tetapi tidak ada yang mengambilnya.

@ feanor07 mengirim tindakan dari dalam get yang membatalkan properti a yang telah dirender adalah aliran balik data, sebelum pengikatan dengan siklus akan mendeteksi dan diam-diam memilih arah maju sebagai pemenang, tetapi ini membutuhkan biaya besar jika ini mengalir melalui beberapa hal dan mengalir kembali ke sumbernya.

Pada dasarnya Anda memiliki ketergantungan siklik dan Anda memerlukan data untuk mengalir ke bawah, jangan membuat kesalahan sebelum Anda menjalankan validasi. Anda dapat memvalidasi dalam komponen induk yang menghasilkan model dan kesalahan untuk merender formulir di dalam bloknya.

@feanor07 Ember.run.scheduleOnce... tidak bekerja, tetapi menambahkan hanya satu Ember.run.schedule("afterRender", () => { ... }); ke properti set pertama ditunjukkan oleh jejak tumpukan menghilangkan banyak pesan kesalahan yang mengalir setelah yang awal.

@neilthawani yang mungkin menyembunyikan kesalahan, tetapi tidak serta merta memperbaiki masalah. Kesalahan ini dimaksudkan untuk menunjukkan bahwa Anda menyetel nilai dua kali padahal seharusnya Anda hanya menyetelnya sekali. Dengan menempatkan salah satu dari set di schedule , Anda hanya menunda set kedua sehingga terjadi di runloop yang berbeda. Anda belum memperbaiki masalah inti rendering dua kali ketika Anda hanya perlu merender sekali, hanya menipu Ember agar tidak mengetahui ada masalah karena sekarang render terjadi di runloop terpisah.

@elwayman02 Oh oh. Terima kasih. Pada dasarnya melewatkan intinya sepenuhnya.

Sunting: Setelah berjuang dengan itu, saya memasukkan lebih banyak afterRenders daripada yang saya rasa nyaman. Kami memiliki handler click pada salah satu data kami yaitu komponen yang mengaktifkan tooltip. Menyetel flag isDisplaying dalam Ember.run.schedule("afterRender", () => { ... }); memungkinkan kami untuk men-debug masalah sebenarnya, yang sebenarnya merupakan backtracking di controller yang meminta komponen data dan komponen tooltip.

tl; dr: Saya tidak menyimpannya di sana (mendapat kesalahan Maximum call stack size exceeded juga), tetapi menggunakannya sangat membantu untuk men-debug sampai masalah sebenarnya terungkap.

PSA untuk orang lain yang baru saja meningkatkan: Kesalahan pernyataan "mundur re-render" yang ditingkatkan yang disebutkan oleh @GavinJoyce di atas sebenarnya termasuk dalam Ember 2.11. Juga disarankan bahwa melompat langsung ke 2.11 mungkin bisa membantu.

Kawan, saya butuh bantuan: Kesalahan ini muncul ketika saya mencoba menggunakan properti model yang "milik" yang lain. Saya membuat proyek kosong, dan itu masih menunjukkan hal yang sama. Apa yang saya lakukan salah?

Juga, di back-end saya, saya menggunakan .Net Core dengan JSON API .Net Core (https://github.com/Research-Institute/json-api-dotnet-core) - mengikuti instruksi mereka.

Render UI rusak pada saat ini, namun data dimuat dan saya dapat melihat nilai yang diinginkan.

    // Profile Model:
    import DS from 'ember-data';
    export default DS.Model.extend({
        'firstName': DS.attr(),
        'lastName': DS.attr(),
        'applicationUser': DS.attr(),
        'contactProfile': DS.belongsTo('address', {
            async: true
        }),
        'companyProfile': DS.belongsTo('address'),
        'companyMailingAddress': DS.belongsTo('address'),
        "companyPhysicalAddress": DS.belongsTo('address')
    });

    // Address Model:
    import DS from 'ember-data';
    export default DS.Model.extend({
        'address1': DS.attr(),
        'address2': DS.attr(),
        'city': DS.attr(),
        'state': DS.attr(),
        'zipCode': DS.attr(),
        'country': DS.attr(),
        'website': DS.attr(),
        'phoneNumber1': DS.attr(),
        'phoneExtension1': DS.attr(),
        'phoneNumber2': DS.attr(),
        'phoneExtension2': DS.attr(),
        'email': DS.attr(),
    });
    // Adapter settings
    import DS from 'ember-data';

    export default DS.JSONAPIAdapter.extend({
        namespace: 'api/json',
    });
    DS.JSONAPISerializer.reopen({
        keyForAttribute(key) {
            return key;
        },
        keyForRelationship(key) {
            return key;
        }
    });
    // Route
    import Ember from 'ember';

    export default Ember.Route.extend({
        model() {
            return Ember.RSVP.hash({
                profile: this.store.findRecord('profile', 1)
            });
        }
    });

    // Template
   {{model.profile.contactProfile.address1}}

dan kesalahan yang saya dapatkan:
Pernyataan Gagal: Anda memodifikasi "model.profile.contactProfile" dua kali pada@model:profile::ember543:1> dalam satu render. Itu diberikan dalam " template:fuels-ember/internal/profile/template.hbs " dan dimodifikasi dalam " template:fuels-ember/internal/profile/template.hbs ". Ini tidak dapat diandalkan dan lambat di Ember 1.x dan tidak lagi didukung. Lihat https://github.com/emberjs/ember.js/issues/13948 untuk detail lebih lanjut.

PS: Saya telah mencoba menggunakan metode Ember.computed untuk mendapatkan properti, dan sepertinya berhasil. Apakah ini diperlukan?

Pembaruan: Saya juga menemukan bahwa data dimuat dengan baik di dalam helper {{#each}}, tetapi tidak langsung pada template.

@lbarsukov
Mungkin ini terkait dengan https://github.com/emberjs/data/issues/5023 di mana backtracking re-render disebabkan oleh hubungan dalam respons jsonapi Anda yang memiliki set properti links .

Ini adalah masalah bagi saya, yang dimulai setelah Ember Data 2.13.2. Coba gunakan ember-data: 2.13.2 untuk melihat apakah ini menyelesaikan masalah Anda.

@daniel-de-wit Acungan jempol untuk master di sini - ini benar-benar berfungsi. Sekarang melakukan apa yang saya butuhkan untuk melakukan dan saya senang dengan itu.

@lbarsukov @daniel-de-wit Kami telah merilis versi baru data ember yang memperbaiki masalah ini.

@lbarsukov Saya pikir ini ada hubungannya dengan hubungan yang Anda tetapkan. Ada kemungkinan besar satu ( atau beberapa ) dari belongsTo seharusnya hasMany .

Katakanlah Anda memiliki dua model, Pertanyaan dan Jawaban. Jika Anda mengembalikan 10 jawaban atas pertanyaan, tetapi setiap pembuat serial pertanyaan mengacu pada jawabannya, Anda _memiliki_ untuk mendefinisikan hubungan dengan benar.

// Question Model:
    export default DS.Model.extend({
        'answers': DS.hasMany('answers'), // if you never reference question.answers you can omit this
        ...
    });

// Answer Model:
    export default DS.Model.extend({
        'question': DS.belongsTo('question'),
        ...
    });

Ketika data menemukan mendefinisikan beberapa pasangan pertanyaan/jawaban, mengharapkan hubungan 1-1 di mana tidak ada, itu menyimpulkan pertanyaan telah dimodifikasi di tengah render.

Dari posting awal, beberapa kait disebutkan:

Ini adalah contoh yang cukup ekstrim, tetapi menggambarkan masalahnya. Selain init, didInitAttrs, didReceiveAttrs, willInsertElement dan willRender juga terjadi secara sinkron selama proses rendering. Selain itu, backtracking sering menjadi masalah yang timbul dari perilaku properti terikat dua arah.

Mengapa kait didInsertElement dan didRender bekerja seperti pesona tetapi kait lainnya gagal dengan kesalahan twice render ?

@BenjaminHorn @ Blackening999 @Dhaulagiri @DingoEatingFuzz @ Gaurav0 @GavinJoyce @Redsandro @TRMW @ Turbo87 @aklkv @alidcastano @backspace @bdiz @bgentry @bjornharrtell @bryanhickerson @buschtoens @caseklim @cbou @chancancode @danaoira @ daniel-de-wit @fivetanley @fotinakis @gabrielgrant @ghost @jakesjews @janmisek @joukevandermaas apakah ini masih menjadi masalah, mungkin kita harus tutup, bagaimana menurutmu?

Saya memperbaiki setiap contoh kesalahan di aplikasi saya.

Setiap kali saya menemukan ini, saya dapat mengatur ulang hal-hal sehingga itu tidak akan terjadi lagi, jadi saya pikir tidak apa-apa untuk menutupnya.

Ya, silakan tutup

akhir zaman

👍

Maaf mengangkat masalah lama.

Katakan misalnya saya sedang merender

{{this.myBool}}

dan kesalahannya adalah Error: Assertion Failed: You modified "myBool" twice

Saya dapat memperbaiki kesalahan dengan mengubahnya menjadi:

{{if this.myBool true false}}

Demikian pula, jika pengikatan nama kelas menyebabkan masalah

Saya bisa berubah:

classNameBindings: ['myBool']

ke

classNameBindings: ['myBool:yes:no']

Jika saya bisa membungkam peringatan seperti ini, mengapa Ember tidak bisa menanganinya untuk saya?

Berikut adalah kode demo yang saya gunakan:

https://ember-twiddle.com/db7f6e382bd0b1de91447881eebb62a5?openFiles=templates.components.my-component.hbs%2C

Tak satu pun dari hal-hal itu "memperbaiki" masalah. Entah Anda beralih ke mode produksi, atau ada bug dalam kode pernyataan/deteksi. Bagaimanapun, Anda perlu memperbaiki sisi yang memberikan/menetapkan nilai, bukan sisi yang mengkonsumsinya.

Oke. Terima kasih. Saya memahami masalah lacak balik yang diuraikan dalam posting asli ini karena memiliki set eksplisit

Tapi di demo twiddle saya, tidak ada set sejauh yang saya bisa lihat.

_Edit_ Itu salah, maksud saya tidak ada set berasal dari _subsequent_ bagian dari template seperti yang ada pada contoh

Hm, saya tidak mendapatkan kesalahan di twiddle, apa urutan klik yang harus saya lakukan?

Klik buka, lalu klik tutup. Tetapi tombol tutup dari komponen anak yang dihasilkan, bukan induknya.

Saya mengerti, masalahnya adalah bahwa selama teardown, focusOut dipanggil pada komponen yang memanggil set pada properti yang sudah dirender. Saya tidak 100% yakin bagaimana komponen kehilangan fokus dan waktu semantik. Saya cukup yakin bahwa variasi yang Anda coba hanya membingungkan sistem pelacakan dan menutupi masalah yang mendasarinya. Mari kita lacak ini di edisi baru? Saya tidak yakin apakah itu masalah yang valid, tetapi mari kita lakukan penyelidikan di sana.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat