Salesforce RefreshView API
1. 核心概念
RefreshView API 是 Salesforce 提供的一种机制,用于 局部刷新组件数据 (而非整个页面),确保组件与外部数据源(如数据库、Apex、GraphQL)保持同步。它适用于 用户触发 (如点击按钮)或 程序自动触发(如数据变更后自动刷新)的场景。
2. 核心功能
- 局部刷新:仅刷新需要更新的组件或组件树(称为 "view")。
- 统一标准 :通过
lightning/refresh
模块提供标准化的刷新接口。 - 兼容性:支持 LWC 和 Aura 组件(但 Aura 基础组件不支持)。
- 灵活控制:可指定刷新范围(单个组件、父组件及其子组件等)。
3. 使用场景
-
用户触发刷新
- 例如:点击按钮刷新当前组件数据。
- 例如:下拉页面触发类似 iOS 的 Pull-to-Refresh 功能。
-
程序自动触发刷新
- 例如:某个组件修改了数据(如通过 Apex 更新记录),其他订阅该数据的组件自动刷新。
- 例如:定时器每隔 5 分钟刷新实时数据。
4. RefreshView API vs 其他方法
方法 | 适用场景 | 示例 |
---|---|---|
RefreshView API |
需要刷新整个组件或组件树(如父组件触发子组件刷新)。 | 父组件点击按钮刷新子组件数据。 |
refreshApex |
刷新通过 @wire 获取的 Apex 数据(如重新调用 Apex 方法)。 |
子组件通过 @wire 获取 Account 数据,点击按钮后调用 refreshApex 。 |
notifyRecordUpdateAvailable |
通知 LDS 刷新记录数据(当记录通过非 LDS 机制更新时)。 以及Aura组件。 | 通过 Apex 更新 Account 后,调用 notifyRecordUpdateAvailable 强制刷新 LDS。 |
5. 注意事项
-
Aura 组件限制
- Aura 基础组件(如
lightning:datatable
)不支持 RefreshView API。 - 自定义 Aura 组件需使用
$A.get('e.force:refreshView').fire()
实现类似功能。
- Aura 基础组件(如
-
安全架构差异
- 在启用 Lightning Locker 或 Lightning Web Security (LWS) 的组织中,注册容器和处理程序的方式可能不同。
-
性能优化
- 避免过度刷新,仅在必要时触发刷新操作(如数据变更后)。
如何使用 RefreshView API
在 Salesforce 的 Lightning Web Components (LWC) 中,registerRefreshHandler()
和 registerRefreshContainer()
是用于处理组件刷新逻辑的两个关键 API,它们的作用和使用场景有显著区别。以下是详细对比:
特性 | registerRefreshHandler() |
registerRefreshContainer() |
---|---|---|
作用对象 | 单个组件 | 容器组件(管理子组件) |
触发逻辑 | 组件自身执行刷新逻辑 | 容器触发子组件刷新逻辑 |
是否需要子组件注册 | ❌ 不需要(组件独立刷新) | ✅ 需要子组件注册 registerRefreshHandler |
返回值要求 | 必须返回 Promise (如 refreshApex ) |
必须返回 Promise |
典型使用场景 | 数据加载组件(如 @wire 组件) |
容器组件(如 lightning-card ) |
事件传播 | 不控制子组件刷新 | 控制子组件刷新顺序和范围 |
1. 引入模块
要使用 RefreshView API,需导入 lightning/refresh
模块。该模块提供了以下核心功能:
RefreshEvent
:用于触发刷新的事件。- 注册方法:允许组件注册为刷新容器或刷新处理程序。
- 状态定义 :如
RefreshComplete
、RefreshCompleteWithError
、RefreshError
。
2. 注册刷新处理程序(Register Refresh Handler)
组件需要注册为刷新处理程序,才能参与数据刷新流程。通常在 connectedCallback()
中注册,并在 disconnectedCallback()
中注销。
关键步骤
- 注册处理程序
使用registerRefreshHandler()
方法注册回调函数。 - 注销处理程序
在组件销毁时使用unregisterRefreshHandler()
避免内存泄漏。 - 刷新逻辑
回调函数需返回一个Promise
,用于控制刷新流程是否继续。
代码示例
javascript
import { LightningElement } from 'lwc';
import { registerRefreshHandler, unregisterRefreshHandler } from 'lightning/refresh';
export default class RefreshHandler extends LightningElement {
refreshHandlerID;
connectedCallback() {
// 注册刷新处理程序(LWS 下直接传 this)
this.refreshHandlerID = registerRefreshHandler(this, this.refreshHandler);
}
disconnectedCallback() {
// 注销处理程序
unregisterRefreshHandler(this.refreshHandlerID);
}
refreshHandler() {
// 刷新逻辑(如重新获取数据)
return new Promise((resolve) => {
// 模拟数据获取
setTimeout(() => {
console.log('数据刷新完成');
resolve(true); // 返回 true 表示刷新成功
}, 1000);
});
}
}
安全架构差异
-
Lightning Web Security (LWS)
直接传入
this
和回调函数:kotlinregisterRefreshHandler(this, this.refreshHandler);
-
Lightning Locker
需传递
this.template.host
并绑定this
:kotlinregisterRefreshHandler(this.template.host, this.refreshHandler.bind(this));
回调函数要求
-
返回 Promise
resolve(true)
:允许继续刷新子组件。resolve(false)
:阻止刷新子组件。
-
处理 UI 更新
- 显示加载动画(如 Spinner)。
- 数据同步后更新组件状态。
3. 触发刷新事件(Signal a Refresh)
通过 RefreshEvent
事件触发刷新,任何组件均可调用。
代码示例
scala
import { LightningElement } from 'lwc';
import { RefreshEvent } from 'lightning/refresh';
export default class RefreshButton extends LightningElement {
// 点击按钮触发刷新
beginRefresh() {
this.dispatchEvent(new RefreshEvent());
}
}
事件传播规则
RefreshEvent
遵循 DOM 冒泡规则。- 最近的注册容器会捕获事件并启动刷新流程。
4. 注册刷新容器(Register Refresh Container)
容器组件需注册为刷新容器,以接收 RefreshEvent
并启动刷新流程。
关键步骤
- 注册容器
使用registerRefreshContainer()
注册回调函数。 - 注销容器
在组件销毁时调用unregisterRefreshContainer()
。 - 处理刷新流程
回调函数接收一个Promise
,用于监听刷新状态。
代码示例
javascript
import { LightningElement } from 'lwc';
import {
registerRefreshContainer,
unregisterRefreshContainer,
REFRESH_COMPLETE,
REFRESH_COMPLETE_WITH_ERRORS,
REFRESH_ERROR
} from 'lightning/refresh';
export default class RefreshContainer extends LightningElement {
refreshContainerID;
connectedCallback() {
// 注册刷新容器(LWS 下直接传 this)
this.refreshContainerID = registerRefreshContainer(this, this.refreshContainer);
}
disconnectedCallback() {
// 注销容器
unregisterRefreshContainer(this.refreshContainerID);
}
refreshContainer(refreshPromise) {
console.log('开始刷新...');
// 监听刷新状态
return refreshPromise.then((status) => {
if (status === REFRESH_COMPLETE) {
console.log('刷新完成');
} else if (status === REFRESH_COMPLETE_WITH_ERRORS) {
console.warn('部分组件刷新失败');
} else if (status === REFRESH_ERROR) {
console.error('刷新失败');
}
});
}
}
容器回调的作用
- 控制刷新流程:决定是否继续刷新子组件。
- 状态反馈:显示加载动画、错误提示(如 Toast)。
- 性能监控:记录刷新开始和结束时间。
5. 刷新流程的执行顺序
-
广度优先遍历:容器按层级顺序执行刷新。
- 父组件刷新完成后,再刷新子组件。
- 刷新会在事件捕获的时候触发
- 父组件不会主动刷新子组件,子组件必须独立注册自己的刷新逻辑。
-
示例:
arduino// 容器结构: // ParentContainer → ChildHandler // 刷新顺序:ParentContainer → ChildHandler
6. 状态定义与错误处理
状态 | 含义 |
---|---|
REFRESH_COMPLETE |
刷新成功完成。 |
REFRESH_COMPLETE_WITH_ERRORS |
部分组件刷新失败,但整体流程继续。 |
REFRESH_ERROR |
刷新失败,流程终止。 |
错误处理示例
javascript
refreshHandler() {
return new Promise((resolve) => {
fetch('/api/data')
.catch(() => {
console.error('数据获取失败');
resolve(false); // 阻止继续刷新子组件
});
});
}
总结
- RefreshView API 是 Salesforce 中局部刷新组件数据的标准方式,适用于复杂的数据同步场景。
- 核心方法 :
registerRefreshHandler/registerRefreshContainer
(注册刷新逻辑)、refresh
(触发刷新)、refreshApex
(刷新 wire 数据)、notifyRecordUpdateAvailable
(通知 LDS 刷新)。 - 最佳实践 :结合
@wire
服务和 LDS 实现高效数据同步,避免全页刷新以提升用户体验。