在LWC类型的Qucik Action触发Apex并刷新页面及组件

566 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

需求描述

在contact上点击lwc类型的quick action时,需要做2件事:

#1. 更新contact的firstname = now;
#2. insert reading records;

并期待2种结果:
#1. 标准的contact lightning page被更新,包括detail page和related list;
#2. 自定义的contact组件 (用于展示contact的基本信息,如firstname)被更新;

问题描述

  1. 当使用下面方法时,只有标准的Contact detail page被刷新
import { LightningElement, api } from 'lwc';
import { CloseActionScreenEvent } from 'lightning/actions';
import { updateRecord } from 'lightning/uiRecordApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent'
import initReadings from '@salesforce/apex/ReadingsStub.initReadings'

export default class FetchReadings extends LightningElement {
    @api recordId;

    renderedCallback() {
        initReadings({clientId: this.recordId})
        .then(()=>{
            const toast = new ShowToastEvent({
                title: 'Readings Ready!',
                message: 'Fetch readings finished.',
                variant: 'success'
            });
            
            this.dispatchEvent(toast);
            this.dispatchEvent(new CloseActionScreenEvent());

            // Only refresh standard contact detail page
            updateRecord({fields: {Id: this.recordId}});
        })
        .catch(error => {
            console.log(error)
        });
    }
}

调用updateRecord的测试结果:

  1. 当作如下更新时:
// import { updateRecord } from 'lightning/uiRecordApi';

    // Only refresh standard contact detail page
    // updateRecord({fields: {Id: this.recordId}});

    // Only update standard contact page including detail & related list.
    eval("$A.get('e.force:refreshView').fire();");

调用eval("$A.get('e.force:refreshView').fire();")的测试结果:refresh std detail page & related list

通过上面的尝试,我们已解决标准界面的信息刷新,但是自定义组件Current Contact和Recommend Plans未被刷新。因此接下来问题变成如何在无Hierarchy的自定义组件间通信。

组件间通信

知识梳理:

  1. 在有Hierarchy组件间,我们可以通过CustomEvent进行事件冒泡向上传递消息,而父对子的事件,可以通过传组件属性或者在父组件直接调用子组件方法完成;

  2. 在非Hierarchy组件间,我们可以通过Pubsub Model, Platform Event, Lightning Message Service (LMS) 以及 Streaming API来完成。

问题深化:这个场景,要把用户体验做到极致,我们除了需要考虑自定义组件间通信,即FetchMockData -> Current Contact, Recommend Plans外,还需要考虑用户在标准组件上修改Contact Detail信息,或是创建 / 删除Readings记录后同样需要刷新Current Contact, Recommend Plans。

通信方案比选

  1. Pubsub Model: 事件可以被fire,但无法被capture,且当记录通过标准组件变更时,无法自定义代码触发事件。
  2. Platform Event: 此方法可以实现极致用户体验。我们可以在Readings上创建After事务的Trigger来publish事件,然后在自定义组件上捕获并refreshView。

使用platform event参考:salesforce.stackexchange.com/questions/3…

LWC Quick Action注意事项

  1. connectedCallback调用apex method时,$recordId为undefined (因此需在renderedCallback下传id调用apex),但在非Quick Action场景使用connectedCallback可以,详见LWC Quick Action - recordId propertyindefined in ConnectedCallback context
  2. 使用wire属性或方法调用apex method时,不能做除Read外的CUD操作,详见LWC开发参考