Anak LWC menyimpan data usang dengan kueri Apex @wired, Induk tidak dapat menyegarkanApex () pada anak dengan querySelector () karena anak disembunyikan oleh if: true. Apa yang harus dilakukan?
struktur aplikasi singkat (lihat gambar): Daftar komponen anak "Item baris" di sebelah kanan (hanya satu massal 1601xCC5Bulk di gambar ini), wadah dengan palet di sebelah kiri. << Allocate btn membuka modal anak lain dengan formulir (if: true ..) daftar pilih formulir ini menggunakan apex @wire untuk hanya menampilkan palet kosong, jadi ini disegarkan oleh pengontrol formulir itu sendiri setelah DML.

Masalah muncul saat mengganti jumlah palet oleh orang tua misalnya, menggunakan tombol merah di sebelah kanan. DML ini menghapus wadah bersama dengan palet.
Tetapi jika formulir tersembunyi dibuka lagi, nilai palet lama masih ada sebagai nilai daftar pilihan, saya perlu menyegarkan data itu. tapi anak ini tersembunyi, jadi tidak bisa dijangkau oleh standar: parent -> querySelector (child2) .method ()
- Maaf untuk pertanyaan newb: Apakah ada cara untuk mengakses metode komponen tersembunyi?
- Saya juga berpikir untuk memindahkan panggilan ke kueri Apex ke komponen induk (mudah dipicu), lalu meneruskannya ke modal anak sebagai argumen api, jadi ketika modal muncul itu akan mendapatkan data yang diperbarui. ini terasa agak salah untuk dilakukan, karena orang tua mengangkat beban anak. (mungkin saya salah)
- Saya juga berpikir untuk menggunakan child renderedCallback untuk kueri puncak itu, tetapi takut dengan perulangan render yang tak terbatas?
- Menonaktifkan caching apex auraEnabled akan menjadi hal yang menyenangkan, tetapi tampaknya tidak mungkin.
Berikut adalah markup tulang telanjang, yang hanya menampilkan semua bagian yang terlibat
=== ORANG TUA (dengan 2 anak) ===
HTML
<template for:each={lineItems.data} for:item="lineItem">
<lightning-layout-item key={lineItem.Id} size="12">
<c-packing-list-line-item-card lineitem={lineItem} onallocatebuttonpress={openAllocationModal}></c-packing-list-line-item-card>
</lightning-layout-item>
</template>
<template if:true={isLineItemModalOpen}>
<c-packing-list-allocation-modal recordid={recordId} oncloseallocationmodal={closeAllocModal} onproductallocated={refreshData}></c-packing-list-allocation-modal>
</template>
JS
openAllocationModal(e) {
this.editItemId = e.detail;
this.isLineItemModalOpen = true;
}
closeAllocModal() {
this.isLineItemModalOpen = false;
}
=== ANAK 1: packing-list-line-item-card === (yang di sebelah kanan, menunjukkan detail produk, meneruskan id ke modal)
HTML
<lightning-button variant="brand" label="<< Allocate" data-itemid={lineitem.Id} onclick={openAllocationModal}></lightning-button>
JS
openAllocationModal(e) {
const selectEvent = new CustomEvent('allocatebuttonpress', { detail: e.target.dataset.itemid });
this.dispatchEvent(selectEvent);
}
=== ANAK 2: Alokasi Modal (tampilan bersyarat) ===
HTML
<template if:true={showInsertButton}>
<button class="slds-button slds-button_brand" onclick={handleAllocationInsert}>Insert</button>
</template>
JS (Anda mungkin hanya tertarik pada closeModal () {}, hal lain untuk kelengkapan)
handleAllocationInsert() {
[...]
createRecord(recordInput)
.then((allocId) => {
this.showToast('success', 'Success', 'Product Allocated');
this.handleInsert(this.palletValue);
this.refreshPallets();
})
.catch((error) => {
this.showToast('error', 'Error creating record', error.body.message);
this.closeModal();
});
}
closeModal() {
// On save parent closes modal
console.log('closing 1');
const selectEvent = new CustomEvent('closeallocationmodal');
this.dispatchEvent(selectEvent);
this.spinner = false;
}
handleInsert(palletValue) {
// On save parent refreshes container view
const selectEvent = new CustomEvent('productallocated', {
detail: this.palletcontainers[palletValue].containerId
});
this.dispatchEvent(selectEvent);
this.closeModal();
}
Jawaban
Maaf untuk pertanyaan newb: Apakah ada cara untuk mengakses metode komponen tersembunyi?
Tidak. Anak tersebut secara fisik dihapus dari DOM dan tidak ada lagi sama sekali (kecuali mungkin dalam cache komponen).
Saya juga berpikir untuk memindahkan panggilan ke kueri Apex ke komponen induk (mudah dipicu), lalu meneruskannya ke modal anak sebagai argumen api, jadi ketika modal muncul itu akan mendapatkan data yang diperbarui. ini terasa agak salah untuk dilakukan, karena orang tua mengangkat beban anak. (mungkin saya salah)
Ini sebenarnya cara yang sangat standar untuk melakukan ini. Anak hanya perlu khawatir tentang menampilkan data, itulah yang dirancang untuk dilakukannya. Biasanya merupakan ide yang baik untuk mendapatkan / menyetel data setinggi mungkin dalam hierarki komponen (tetapi tidak lebih tinggi dari yang diperlukan).
Saya juga berpikir untuk menggunakan child renderedCallback untuk kueri puncak itu, tetapi takut dengan perulangan render yang tak terbatas?
Ide buruk, Anda akan mendapatkan loop tak terbatas, seperti yang Anda harapkan. Namun, menggunakan connectedCallback dari komponen bisa masuk akal di sini. Peristiwa ini hanya dipanggil ketika sebuah komponen ditambahkan atau dipindahkan ke DOM, sehingga tidak akan memiliki masalah pengulangan tak terbatas.
Menonaktifkan caching apex auraEnabled akan menjadi hal yang menyenangkan, tetapi tampaknya tidak mungkin.
Itu sangat mungkin, tetapi saya akan menganggap ini sebagai pilihan terakhir. Sebagian besar waktu, data tidak berubah hingga pengguna melakukan sesuatu, jadi caching dapat meningkatkan kinerja. Meskipun demikian, desain Anda juga tampaknya tidak memerlukan panggilan yang sering, jadi menonaktifkan caching mungkin juga dapat diterima.
Sebagai kesimpulan, saya akan mengatakan mengontrol data dari orang tua akan menjadi solusi termudah. Ini juga merupakan solusi yang dapat diterima secara umum dalam banyak kasus, karena komponen turunan biasanya hanya berfungsi dengan data yang diberikan dari induknya. Misalnya, lightning-input
tidak melakukan apa pun dengan server secara langsung, tetapi mengomunikasikan perubahan kepada induk melalui peristiwa. Ini adalah desain yang sangat alami untuk digunakan.
Jika Anda ingin anak-anak terus melakukan pekerjaan, tidak masalah juga, cukup lakukan panggilan refreshApex di connectedCallback Anda, atau nonaktifkan caching. Keduanya harus menyelesaikan masalah Anda, meskipun Anda mungkin ingin menguji pada kumpulan data yang besar untuk melihat opsi mana yang tersedia untuk Anda menawarkan kinerja terbaik.