เด็ก LWC แคชข้อมูลเก่าโดยการสอบถาม @wired Apex ผู้ปกครองไม่สามารถ refreshApex () บนลูกโดย querySelector () เนื่องจากเด็กถูกซ่อนโดย if: true จะทำอย่างไร?
โครงสร้างแอปโดยย่อ (ดูภาพ): รายการส่วนประกอบย่อยของ "รายการโฆษณา" ทางด้านขวา (เพียง 1601xCC5Bulk เดียวในรูปนี้) คอนเทนเนอร์ที่มีพาเลททางด้านซ้าย << จัดสรร btn เปิดโมดอลลูกอื่นด้วยฟอร์ม (ถ้า: จริง .. ) รายการเลือกของแบบฟอร์มนี้ใช้ @wire apex เพื่อแสดงเฉพาะพาเลทที่ว่างเปล่าดังนั้นจึงรีเฟรชโดยตัวควบคุมของฟอร์มเองหลังจาก DML

ปัญหาเกิดขึ้นเมื่อเปลี่ยนจำนวนพาเลทโดยผู้ปกครองเช่นใช้ปุ่มสีแดงทางด้านขวา DML นี้จะลบคอนเทนเนอร์พร้อมกับพาเลท
แต่ถ้าเปิดฟอร์มที่ซ่อนไว้อีกครั้งค่าพาเลทเก่ายังคงแสดงเป็นค่ารายการเลือกฉันต้องรีเฟรชข้อมูลนั้น แต่ลูกนี้ถูกซ่อนไว้จึงไม่สามารถเข้าถึงได้ตามมาตรฐาน: parent -> querySelector (child2) .method ()
- ขออภัยสำหรับคำถาม newb: มีวิธีเข้าถึงวิธีการของส่วนประกอบที่ซ่อนอยู่หรือไม่?
- ฉันยังคิดที่จะย้ายการเรียกไปยัง Apex query ขึ้นไปยังองค์ประกอบหลัก (ง่ายต่อการทริกเกอร์) จากนั้นส่งต่อไปยังโมดอลลูกเป็นอาร์กิวเมนต์ api ดังนั้นเมื่อโมดอลปรากฏขึ้นมันจะได้รับข้อมูลที่อัปเดต รู้สึกผิดนิดหน่อยที่ต้องทำเพราะพ่อแม่ยกภาระให้ลูก (บางทีฉันคิดผิด)
- ฉันยังคิดที่จะใช้ renderedCallback ของเด็กสำหรับแบบสอบถาม apex นั้น แต่กลัวการวนซ้ำการแสดงผลที่ไม่มีที่สิ้นสุด?
- การปิดใช้งานการแคชออร่าเอเพ็กซ์จะเป็นสิ่งที่ดี แต่ดูเหมือนจะเป็นไปไม่ได้
นี่คือมาร์กอัปกระดูกเปลือยซึ่งแสดงเฉพาะส่วนที่เกี่ยวข้องทั้งหมด
=== PARENT (มีลูก 2 คน) ===
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;
}
=== เด็ก 1: รายการบรรจุ - รายการ - รายการ - การ์ด === (อันที่อยู่ทางขวาแสดงรายละเอียดสินค้าส่งรหัสไปยังโมดอล)
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);
}
=== เด็ก 2: โมดอลการจัดสรร (การแสดงเงื่อนไข) ===
HTML
<template if:true={showInsertButton}>
<button class="slds-button slds-button_brand" onclick={handleAllocationInsert}>Insert</button>
</template>
JS (คุณอาจสนใจเฉพาะ closeModal () {} ส่วนอื่น ๆ ก็เพื่อความสมบูรณ์)
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();
}
คำตอบ
ขออภัยสำหรับคำถาม newb: มีวิธีเข้าถึงวิธีการของส่วนประกอบที่ซ่อนอยู่หรือไม่?
ไม่เด็กถูกลบออกจาก DOM ทางกายภาพและไม่มีอยู่เลย (ยกเว้นอาจอยู่ในแคชคอมโพเนนต์)
ฉันยังคิดที่จะย้ายการเรียกไปยัง Apex query ขึ้นไปยังองค์ประกอบหลัก (ง่ายต่อการทริกเกอร์) จากนั้นส่งต่อไปยังโมดอลลูกเป็นอาร์กิวเมนต์ api ดังนั้นเมื่อโมดอลปรากฏขึ้นมันจะได้รับข้อมูลที่อัปเดต รู้สึกผิดนิดหน่อยที่ต้องทำเพราะพ่อแม่ยกภาระให้ลูก (บางทีฉันคิดผิด)
นี่เป็นวิธีมาตรฐานมากในการทำเช่นนี้ เด็กเพียงแค่ต้องกังวลเกี่ยวกับการแสดงข้อมูลซึ่งเป็นสิ่งที่ออกแบบมาเพื่อทำ โดยทั่วไปเป็นความคิดที่ดีที่จะรับ / ตั้งค่าข้อมูลในลำดับชั้นขององค์ประกอบให้สูงที่สุดเท่าที่จะทำได้ (แต่ไม่สูงเกินความจำเป็น)
ฉันยังคิดที่จะใช้ renderedCallback ของเด็กสำหรับแบบสอบถาม apex นั้น แต่กลัวการวนซ้ำการแสดงผลที่ไม่มีที่สิ้นสุด?
คิดไม่ดีคุณจะได้ลูปไม่สิ้นสุดอย่างที่คุณคาดหวัง อย่างไรก็ตามการใช้ connectedCallback ของคอมโพเนนต์อาจสมเหตุสมผลที่นี่ เหตุการณ์นี้จะเรียกเฉพาะเมื่อมีการเพิ่มแร่ที่ย้ายใน DOM ดังนั้นจึงไม่มีปัญหาการวนซ้ำแบบไม่สิ้นสุด
การปิดใช้งานการแคชออร่าเอเพ็กซ์จะเป็นสิ่งที่ดี แต่ดูเหมือนจะเป็นไปไม่ได้
เป็นไปได้อย่างสมบูรณ์แบบ แต่ฉันจะถือว่านี่เป็นทางเลือกสุดท้าย โดยส่วนใหญ่ข้อมูลจะไม่เปลี่ยนแปลงจนกว่าผู้ใช้จะทำอะไรบางอย่างดังนั้นการแคชจะช่วยปรับปรุงประสิทธิภาพได้ กล่าวได้ว่าการออกแบบของคุณดูเหมือนว่าไม่จำเป็นต้องมีการโทรบ่อยๆดังนั้นการปิดใช้งานการแคชจึงเป็นสิ่งที่ยอมรับได้เช่นกัน
สรุปได้ว่าการควบคุมข้อมูลจากผู้ปกครองน่าจะเป็นทางออกที่ง่ายที่สุด นี่เป็นวิธีแก้ปัญหาที่ยอมรับได้โดยทั่วไปในกรณีส่วนใหญ่เนื่องจากโดยทั่วไปแล้วส่วนประกอบย่อยจะทำงานกับข้อมูลที่ได้รับจากผู้ปกครองเท่านั้น ตัวอย่างเช่นlightning-input
ไม่ได้ทำอะไรกับเซิร์ฟเวอร์โดยตรง แต่จะสื่อสารการเปลี่ยนแปลงกับผู้ปกครองผ่านเหตุการณ์ เป็นการออกแบบที่เป็นธรรมชาติอย่างสมบูรณ์แบบที่จะใช้
หากคุณต้องการให้เด็ก ๆ ทำงานต่อไปก็ใช้ได้เช่นกันเพียงแค่มีการโทร refreshApex ใน connectedCallback ของคุณหรือปิดใช้งานการแคช ควรแก้ไขปัญหาของคุณแม้ว่าคุณอาจต้องการทดสอบกับชุดข้อมูลขนาดใหญ่เพื่อดูว่าตัวเลือกใดที่คุณสามารถใช้ได้ให้ประสิทธิภาพที่ดีที่สุด