How to clear draft values in LWC datatable after save

Sep 06 2020

I am working on an LWC datatable application in which I must call an Apex method imperatively, passing it the JSON string of the event.detail.draftValues which it uses to add or update some Sobject records. All of that works fine. The problem is that, after my javascript "Save" function, I want to clear all of those "old" draft values, so my users can start editing fields again without having to refresh the page; but I cannot figure out how to do that. That is, remove the yellow highlighting as shown below.

Entonces, si presionan "Guardar" nuevamente, los valores seleccionados previamente se envían nuevamente al método Apex, que no es óptimo. Estoy intentando ejecutar la función refreshApex (), pero no debe estar funcionando. Se muestran los JS y HTML relevantes. Estaría agradecido si alguien pudiera ayudarme, y me disculpo si no he usado este foro correctamente, ya que es la primera vez que publico.

import { LightningElement, wire, track } from 'lwc';
import getPriceRecords from '@salesforce/apex/FikeStdPriceBookController.getPriceRecords';
import updatePriceRecords from '@salesforce/apex/FikeStdPriceBookController.updatePriceRecords';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class StdPriceBookWorkBench extends LightningElement {

@track productCategorySearchKey = '';
@track productFamilySearchKey = '';
@track productLineSearchKey = '';
@track productSubLineSearchKey = '';
@track productSearchKey = '';
@track productDescriptionSearchKey = '';
@track error;
@track pricesList;

@wire(getPriceRecords, {productCategorySearchKey: '$productCategorySearchKey', productFamilySearchKey: '$productFamilySearchKey',
                       productLineSearchKey: '$productLineSearchKey', productSubLineSearchKey: '$productSubLineSearchKey',
                       productSearchKey: '$productSearchKey', productDescriptionSearchKey: '$productDescriptionSearchKey'})
        

    wiredTargets({
        error,
        data
    }) {
        if (data) {
            this.pricesList = data;  

        } else if (error) {
            this.error = error;
        }
    }


// This is the standard handleSave function, in which I think the problem is to be found.

handleSave(event) {
            
            var draftValuesStr = JSON.stringify(event.detail.draftValues);
            updatePriceRecords({updateObjStr: draftValuesStr})
            .then(result => {
              this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                     message: result + ' price records have been added or updated.',
                     variant: 'success'   
                  })
                   
              );  //End of dispatchEvent
    
                this.draftValues = [];
                refreshApex(this.getPriceRecords);
       
             }).catch(error => {
              // Handle error
            });
      
     }

Aquí está la tabla de datos en mi archivo HTML:

<template if:true={pricesList}>        
     <lightning-datatable data={pricesList} 
                          columns={columns} 
                          key-field="Id"
                          onsave={handleSave}
                          hide-checkbox-column="true"
                          draft-values={draftValues}>
     </lightning-datatable>   
</template>
<template if:true={error}>
    {error}
</template>

Respuestas

1 MatthewSouther Nov 11 2020 at 00:38

He tenido éxito al borrar los valores de borrador en el lightning-datatableeditando directamente la draftValuespropiedad en el lightning-datatableelemento DOM. Esto parece eliminar los botones Guardar y Cancelar y borrar el resaltado amarillo de las celdas que editó:

this.template.querySelector("lightning-datatable").draftValues = [];
arut Sep 06 2020 at 21:00

Debería llamar al ápice de actualización en el valor proporcionado por el servicio de cable y no en el método del ápice en sí. Actualice su llamada de servicio de cable de la siguiente manera

@wire(getPriceRecords, {
    productCategorySearchKey: '$productCategorySearchKey', productFamilySearchKey: '$productFamilySearchKey',
    productLineSearchKey: '$productLineSearchKey', productSubLineSearchKey: '$productSubLineSearchKey',
    productSearchKey: '$productSearchKey', productDescriptionSearchKey: '$productDescriptionSearchKey'
})
wiredTargets(value) {
    // Hold on to the provisioned value so we can refresh it later.
    this.wireResult = value; // track the provisioned value
    const { data, error } = value; // destructure the provisioned value
    
    if (data) {
        this.pricesList = data;  

    } else if (error) {
        this.error = error;
    }
}

y actualice su llamada de actualización del ápice de la siguiente manera:

refreshApex(this.wireResult);

Esto debería llamar al método apex nuevamente y buscar nuevos valores en los this.pricesListque se actualizará la tabla de datos. En un nivel alto, el resto del código se ve bien.