本篇參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript
隨着項目的學習以及trailhead的學習,會遇見自己曾經模糊的定義或者比較浪費時間但是又比較簡單的坑,在此mark一下,共同進行學習參考。
一. 子組件調用后台實現父組件更改后子組件清除cache更新
我們在開發中經常會出現父子component嵌套的情形。有一種場景為子component使用 lightning-record-form或者使用@getRecord去展示一條數據的詳情信息。當父或者兄弟component更新了當前的record的某個字段的值以后,我們需要展示詳情的子component也要實時刷新成最新的數據。下面的demo以@getRecord來講解。
testSon.html:用於展示Account的Industry信息
<template> {accountIndustry} </template>
testSon.js:使用getRecord獲取當前的數據,這個js中有幾個點需要注意:
- getRecord結果集通過一個變量進行承接,當這個值使用refreshApex方法改變以后,salesforce會自動重新執行getRecord方法獲取最新的數據;
- 針對變量的聲明,我們除了可以直接聲明外,還可以使用 get / set進行設置。當父組件對這個變量進行更改后,會先調用set方法,然后調用get方法進行返回,set get在項目中的使用尤為重要,一定要有這個概念。
import { LightningElement, wire, track, api } from 'lwc';
import ACCOUNT_INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
import { getRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '@salesforce/apex';
export default class TestSon extends LightningElement {
accountCached;
@api recordId;
refreshFlag = false;
@wire(getRecord,{ recordId: '$recordId', fields: [ACCOUNT_INDUSTRY_FIELD]})
wiredRecord(record) {
this.accountCached = record;
const { error, data } = record;
if(data) {
if(data.fields) {
this.accountIndustry = data.fields.Industry.value;
}
} else if(error) {
console.log('execute error');
}
}
refreshHandler() {
refreshApex(this.accountCached);
}
get needRefresh() {
return this.refreshFlag;
}
@api set needRefresh(value) {
if(value) {
refreshApex(this.accountCached);
}
this.refreshFlag = value;
}
@track accountIndustry;
}
testParent.html: 嵌入 testSon子組件,旁邊放一個button進行邏輯處理。
<template> <c-test-son need-refresh={needRefresh} record-id={recordId}></c-test-son> <lightning-button value="refresh" label="refresh" onclick={refreshHandler}></lightning-button> </template>
testParent.js:refreshHandler執行后會將Industry值清空,然后設置needRefresh為true。
import { LightningElement, track, api } from 'lwc';
import ACCOUNT_INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
import ACCOUNT_ID_FIELD from '@salesforce/schema/Account.Id';
import { updateRecord } from 'lightning/uiRecordApi';
export default class TestParent extends LightningElement {
@api recordId;
@track needRefresh = false;
refreshHandler() {
const fields = {};
fields[ACCOUNT_ID_FIELD.fieldApiName] = this.recordId;
fields[ACCOUNT_INDUSTRY_FIELD.fieldApiName] = '';
const recordInput = { fields };
updateRecord(recordInput)
.then(() => {
this.needRefresh = true;
})
.catch(error => {
//TODO
});
}
}
所以最終的整體流程為:
1. 初始化展示當前Account數據的Industry的值。

2. 當點擊refresh以后,執行updateRecord方法,industry清空,needRefresh設置為true。當needRefresh設置為true以后,會執行testSon的set方法,因為value為true,執行了refreshApex方法,從而getRecord重新執行達到實時刷新效果。

二. JSON與 Map & Object
我們在項目中前后端會經常用到 JSON進行序列化以及反序列化,也經常會用到Map去進行數據操作等等。
Map使用key-value鍵值對,Object也是用key-value鍵值對。兩者在前后端聲明或者使用傻傻分不清楚,特別是前端使用。在這里針對前端使用通過一張官方文檔的圖進行解釋。這個區別目前僅限於前端。

接下來說一下JSON。JSON我們在前端主要使用的方法主要有兩個: JSON.stringify以及JSON.parse,即序列化成JSON的字符串和反序列化成我們序列化以前的結構。我們在后台經常用到 Map進行serialize轉換,所以我們認為前端仍然可以轉換。這里其實有一個誤區,后台不是所有的Map都可以JSON進行序列化。因為Map的key可以是任何類型,只有符合下面要求的才可以進行JSON的序列化。


所以我們特別是針對前台進行序列化處理時,盡量少用Map,可以聲明Object然后進行序列化處理也同樣可以Map的效果。

三. setInterval在LWC中的使用
我們知道JS默認是同步執行,默認的上下文是this。而setInterval是js中的定時器方法,執行方式是異步執行。上下文為當前的windows。這就導致當我們在執行方法時當前this的引用的變量無法在定時器中使用,下圖demo中結果永遠是1,不會改變。因為initialData的作用域是this,setInterval上下文是windows,無法獲取到this的上下文。

針對異步的操作,我們只需要在方法中將this的上下文進行引用賦值,然后使用引用的變量操作即可。

總結:篇中針對用到的不是很難但是很容易出錯的知識點進行整理。有錯誤的地方歡迎指出,有不懂的歡迎留言。
