LWC alt öğesi, eski verileri @wired Apex sorgusu ile önbelleğe alır, Parent, child üzerinde querySelector () tarafından yenileyemez, çünkü child if: true tarafından gizlenir. Ne yapalım?
kısa uygulama yapısı (resme bakın): Sağda "Satır öğesi" alt bileşenleri listesi (bu resimde yalnızca bir 1601xCC5Yığın), solda paletler bulunan konteyner. << Allocate btn, bir formla başka bir alt model açar (eğer: true ..) bu formun seçim listesi, yalnızca boş paletleri göstermek için @wire apeks kullanır, bu nedenle DML'den sonra formun denetleyicisi tarafından yenilenir.

Örneğin sağdaki kırmızı düğmeyi kullanarak bir ebeveyn tarafından palet miktarını değiştirirken sorun ortaya çıkar. bu DML, paletlerle birlikte kabı siler.
Ancak gizli form tekrar açılırsa, eski palet değerleri hala seçim listesi değerleri olarak mevcut, bu verileri yenilemem gerekiyor. ancak bu alt öğe gizlidir, bu nedenle standart olarak erişilemez: parent -> querySelector (child2) .method ()
- Yeni soru için üzgünüm: Gizli bileşenin yöntemlerine erişmenin bir yolu var mı?
- Ayrıca çağrıyı Apex sorgusuna üst bileşene taşımayı (tetiklemesi kolay), ardından onu bir api argümanı olarak alt modal'a aktarmayı düşünüyordum, böylece modal göründüğünde güncellenmiş verileri alacak. Ebeveyn çocuğun yükünü kaldırdığı için bunu yapmak biraz yanlış geliyor. (belki yanılıyorum)
- Ayrıca bu apex sorgusu için child's renderedCallback'i kullanmayı düşünüyordum, ancak sonsuz render döngülerinden mi korkuyordum?
- AuraEnabled apeksin önbelleğe alınmasını devre dışı bırakmak güzel bir şey olabilir, ancak imkansız görünüyor.
İşte sadece ilgili tüm parçaları gösteren çıplak kemik işaretlemesi
=== EBEVEYN (2 çocuklu) ===
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;
}
=== ÇOCUK 1: paketleme listesi satır öğesi kartı === (sağdaki, ürün ayrıntılarını gösterir, kimliği modale geçirir)
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);
}
=== ÇOCUK 2: Tahsis Modeli (koşullu görüntüleme) ===
HTML
<template if:true={showInsertButton}>
<button class="slds-button slds-button_brand" onclick={handleAllocationInsert}>Insert</button>
</template>
JS (muhtemelen yalnızca closeModal () {} ile ilgileniyorsunuz, diğer şeyler eksiksizlik içindir)
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();
}
Yanıtlar
Yeni soru için üzgünüm: Gizli bileşenin yöntemlerine erişmenin bir yolu var mı?
Hayır çocuk fiziksel olarak DOM çıkarılır ve artık yok edilir hiç (bir bileşen önbellekte muhtemelen hariç).
Ayrıca çağrıyı Apex sorgusuna üst bileşene taşımayı (tetiklemesi kolay), ardından onu bir api argümanı olarak alt modal'a aktarmayı düşünüyordum, böylece modal göründüğünde güncellenmiş verileri alacak. Ebeveyn çocuğun yükünü kaldırdığı için bunu yapmak biraz yanlış geliyor. (belki yanılıyorum)
Bu aslında bunu yapmanın çok standart bir yoludur. Çocuğun yalnızca verileri gösterme konusunda endişelenmesi gerekir, bu da bunun için tasarlandığı şeydir. Bileşen hiyerarşisinde olabildiğince yüksek veri almak / ayarlamak genellikle iyi bir fikirdir (ancak gerekenden daha yüksek olmamalıdır).
Ayrıca bu apex sorgusu için child's renderedCallback'i kullanmayı düşünüyordum, ancak sonsuz render döngülerinden mi korkuyordum?
Kötü fikir, beklediğiniz gibi sonsuz döngüler elde edeceksiniz. Ancak, bileşenin ConnectedCallback işlevini kullanmak burada mantıklı olabilir. Bu olay, yalnızca DOM'a bir bileşen eklendiğinde veya taşındığında çağrılır, böylece sonsuz döngü sorunları yaşamaz.
AuraEnabled apeksin önbelleğe alınmasını devre dışı bırakmak güzel bir şey olabilir, ancak imkansız görünüyor.
Bu tamamen mümkün, ancak bunu son çare olarak görüyorum. Çoğu zaman, veriler kullanıcı bir şey yapana kadar değişmez, bu nedenle önbelleğe alma performansı artırabilir. Bununla birlikte, tasarımınız da sık aramalara ihtiyaç duymuyor gibi görünüyor, bu nedenle önbelleğe almayı devre dışı bırakmak da muhtemelen kabul edilebilir.
Sonuç olarak, verileri ebeveynden kontrol etmenin en kolay çözüm olacağını söyleyebilirim. Bu aynı zamanda çoğu durumda genel olarak kabul edilebilir bir çözümdür, çünkü alt bileşenler tipik olarak yalnızca ebeveynden verdikleri verilerle çalışır. Örneğin lightning-input
, sunucuyla doğrudan hiçbir şey yapmaz, ancak değişiklikleri olaylar aracılığıyla üst öğeye iletir. Kullanması tamamen doğal bir tasarım.
Çocukların çalışmaya devam etmesini istiyorsanız, bu da sorun değil, sadece Connecallback'inizde bir yenilemeApex çağrısı yapın veya önbelleği devre dışı bırakın. Kullanabileceğiniz seçeneklerden hangisinin en iyi performansı sunduğunu görmek için büyük bir veri kümesi üzerinde test etmek isteyebilirsiniz, ancak her ikisi de sorununuzu çözmelidir.