本篇參考:
https://developer.salesforce.com/docs/component-library/bundle/lightning-emp-api/documentation
salesforce零基礎學習(九十六)Platform Event淺談
Salesforce LWC學習(五) LDS & Wire Service 實現和後臺資料互動 & meta xml配置
背景: 我們在記錄的詳情頁面,除標準的layout以外,實際工作中也會新增各種各樣的component來滿足實際業務的需要,有一些是標準元件,有一些是自定義元件。自定義元件間的修改和互動很好弄,我們可以透過 notifyRecordUpdateAvailable搞定(Lighting Data Service)LDS的快取問題,透過 refreshApex搞定 call apex方法的問題,透過 dispatchEvent / handler方式來搞定父子元件通訊的事情,透過pub / sub事件模型來搞定跨元件通訊問題,透過 lightning message service或者 dynamic interaction也可以搞定跨元件通訊問題。如上的內容都是自定義元件之間或者自定義元件的行為渲染到標準元件。那我們如何針對標準元件的更新作用到自定義頁面,然後自定義頁面捕捉到這些事件操作呢? 本篇提供兩種思路。
需求: 當使用者在Account詳情頁面更新資料時,不管使用 quick action的Edit還是 Inline Edit,當Account的Name包含Test的字樣,顯示一個toast資訊。
一. 基於Lightning Data Service(LDS)
這個demo可以基於getRecord的這個wire adapter來實現。因為 getRecord以及標準UI都共用同一個version的資料,所以當標準UI因為使用者修改以後,我們透過 getRecord也同樣可以自動收到最新的version的資料,所以我們可以基於 getRecord的這個wire adapter來實現。
import { LightningElement, api, wire } from 'lwc'; import { ShowToastEvent } from 'lightning/platformShowToastEvent'; import { getRecord } from 'lightning/uiRecordApi'; import NAME_FIELD from "@salesforce/schema/Account.Name"; export default class toastDemo extends LightningElement { @api recordId; @wire(getRecord, { recordId: '$recordId', fields: [NAME_FIELD]}) // eslint-disable-next-line no-unused-vars wiredAccount(data, error) { if (data.data && data.data.fields && data.data.fields.Name) { if(data.data.fields.Name.value.includes('test')) { this.showToast(); } } else if(error) { console.log('error'); } } showToast() { const evt = new ShowToastEvent({ message: 'Name contains test', variant: 'info', }); this.dispatchEvent(evt); } }
效果演示:將這個元件放在 lightning record page中
二. 基於Platform Event 訂閱實現
如果對Platform Event不瞭解的,歡迎檢視以前的部落格內容。思路為當Account Name變動以後,釋出一個Account的Platform Event,lwc端用來訂閱這個Platform Event,對訂閱的結果進行解析,如果滿足了預期,則進行邏輯處理。
1. 建立Platform Event的表以及欄位。
2. 透過Flow或者Trigger,Account Name包含test情況下,釋出Platform Event.
3. lwc進行訂閱:這裡看一下加粗的兩行,messageCallback函式看上去有自己的上下文,如果不傳遞進去,獲取的recordId則為 undefined, context也相同。
import { LightningElement, api, wire } from "lwc"; import { ShowToastEvent } from "lightning/platformShowToastEvent"; import { subscribe, unsubscribe, onError, setDebugFlag, isEmpEnabled } from "lightning/empApi"; export default class toastDemo extends LightningElement { channelName = "/event/Account_Change__e"; @api recordId; get changedRecordId() { return this.targetedRecordId; } subscription = {}; // Initializes the component connectedCallback() { // Register error listener this.registerErrorListener(); const currentRecordId = this.recordId; const context = this; const messageCallback = function (response) { // Response contains the payload of the new message received let event = response.data.payload; if (event.Account_Id__c == currentRecordId) { const evt = new ShowToastEvent({ message: "Name contains test", variant: "info" }); context.dispatchEvent(evt); } }; // Invoke subscribe method of empApi. Pass reference to messageCallback subscribe(this.channelName, -1, messageCallback).then((response) => { // Response contains the subscription information on subscribe call console.log("Subscription request sent to: ", JSON.stringify(response.channel)); this.subscription = response; }); } disconnectedCallback() { unsubscribe(this.subscription, (unsubResp) => { console.log("unsubscribe() response: ", JSON.stringify(unsubResp)); }); } registerErrorListener() { // Invoke onError empApi method onError((error) => { console.log("Received error from server: ", JSON.stringify(error)); // Error contains the server-side error }); } }
效果:
總結:本篇主要介紹的是標準頁面編輯資料情況下自定義的lwc頁面如何進行捕捉然後做一些邏輯,其中LDS方式固然好用,但是沒有那麼靈活,如果需求簡單,推薦使用LDS方式,否則可以考慮訂閱Platform Event來實現。篇中有錯誤地方歡迎指出,有不懂歡迎留言。