创建服务端 Apex 控制器类(01 Create a Server-side Apex Controller Class)
我们从最底层开始:Apex 控制器类。你的组件需要数据来展示,而控制器就是你获取数据的途径。在本单元中,你将创建一个带 @AuraEnabled 方法的类——这个注解把你的 Apex 代码暴露给 Lightning 组件框架。我们会用一条简单的 SOQL 查询来获取与某个 Account 关联的 Contact,这将成为整个组件的数据源。
Aura 组件简介(Introduction to Aura Components)
Lightning Component 框架(Lightning Component framework) 是一个 UI 框架,用于为移动端和桌面端开发动态 Web 应用。在这个 Quick Start 中,你将创建一个简单的 Lightning 组件,用来渲染组织里某个 Account 的联系人列表:先创建 Apex 控制器类,再创建 Lightning 组件和事件处理器,最后在组件中渲染联系人列表。
在动手之前,有些重要背景值得了解:
- Aura 是最初的 Lightning 组件框架——仍部署在许多组织中,为遗留用途提供支持。
- Lightning Web Components(LWC) 现在是在 Salesforce 上构建 UI 的首选方式。本模块面向维护现有 Aura 组件的管理员。
- SLDS 2 在 Spring '25 推出,带来了全新的 CSS 框架和样式钩子(styling hooks)。若要享受 SLDS 2 的收益,应把 Aura 组件升级为 Lightning Web Components 或 Lightning base components,并使用样式钩子。
虽然如此,这个 Quick Start 仍是理解组件模型以及服务端数据如何流入 UI 的绝佳方式——你写的代码真实且可用,但做新开发时通常应转向 LWC。
构建 Apex 控制器(一):创建类(Build an Apex Controller (1): Create the Class)
首先创建 Apex 类的空壳,它将作为你组件的数据层。
- 在 Trailhead Playground 中,点击设置齿轮,选择 Developer Console。
- 选择 File | New | Apex Class。
- 类名输入
MyContactListController,点击 OK。
现在你有了一个空类:
public class MyContactListController {
// 方法写在这里
}
为什么要用一个单独的控制器类?
- 关注点分离——数据逻辑与 UI 标记解耦
- 可复用性——同一个 Apex 方法可以被多个组件调用
- 可测试性——Apex 类可以独立于 UI 进行单元测试
注意命名约定:控制器类名与组件名一致(MyContactListController 对应 MyContactList)。这不是框架强制要求,但能让代码库更易导航。
构建 Apex 控制器(二):@AuraEnabled 方法(Build an Apex Controller (2): The @AuraEnabled Method)
在类的类体({ } 花括号之间)中,添加查询 Contact 的方法:
@AuraEnabled
public static List<Contact> getContacts(Id recordId) {
return [SELECT Id, FirstName, LastName, Email, Phone
FROM Contact WHERE AccountId = :recordId];
}
然后选择 File | Save。
关键注解与关键字:
- @AuraEnabled——把方法暴露给 Lightning 组件(没有它,JavaScript 无法调用)。标注了 @AuraEnabled 的 Apex 方法才能从 Lightning 组件调用。
- public static——全局可访问,无需实例即可调用。
- List<Contact>——返回类型:一组 Contact 记录。
- :recordId——SOQL 绑定变量(bind variable),把方法参数安全地注入查询,防止 SOQL 注入。
这条带 WHERE 子句的简单 SELECT,是 Lightning 组件中最常见的模式:给定父记录 Id,返回相关的子记录。数据层就绪了——下一步构建 UI。
创建 Aura 组件(02 Create an Aura Component)
Apex 控制器就绪后,我们来构建真正的 UI——一个将显示在 Account 记录页上的 Aura 组件。你将在开发者控制台中创建组件包(component bundle),定义用于存储数据的属性(attribute),接入 Lightning Data Service 加载 Account 记录,并用 lightning:card 基础组件作为容器。
创建组件并添加到记录页(一):组件设置(Create and Add an Aura Component to the Record Page (1): Component Setup)
一个 Aura 组件是标记(markup)、JavaScript 和 CSS 的组合。先创建组件包,并把它连接到你的 Apex 控制器:
- 在开发者控制台中,选择 File | New | Lightning Component。
- 组件名输入
MyContactList。 - 勾选 Lightning Record Page,点击 Submit。
- 在
aura:component标签上添加对 Apex 控制器的引用,配置如下:
<aura:component controller="MyContactListController"
implements="flexipage:availableForRecordHome,force:hasRecordId"
access="global" >
这个配置的作用:
- controller=——把组件链接到你的 Apex 类(让
c.getContacts可用) - flexipage:availableForRecordHome——让管理员能把它加到 Lightning 记录页
- force:hasRecordId——让组件能访问当前记录的 Id
- access="global"——在整个组织内可见
勾选 Lightning Record Page 很关键——它会加上 flexipage:availableForRecordHome 接口,使你的组件出现在 Lightning App Builder 的组件面板里。这些 implements 声明是你组件与 Salesforce 平台之间的"契约",声明了组件能做什么、能用在哪里。
创建组件并添加到记录页(二):属性与 LDS(Create and Add an Aura Component to the Record Page (2): Attributes & LDS)
在第 2 行添加以下代码,用 aura:attribute 和 Lightning Data Service 定义组件的数据模型:
<aura:attribute name="recordId" type="Id" />
<aura:attribute name="Account" type="Account" />
<aura:attribute name="Contacts" type="Contact" />
<aura:attribute name="Columns" type="List" />
<force:recordData aura:id="accountRecord"
recordId="{!v.recordId}"
targetFields="{!v.Account}"
layoutType="FULL"
/>
<lightning:card iconName="standard:contact" title="{! 'Contact List for ' + v.Account.Name}">
<!-- Contact list goes here -->
</lightning:card>
aura:attribute 用于在 Aura 组件内存储数据。属性就是组件的内部状态:
- recordId——由
force:hasRecordId自动填充当前记录 Id - Account——存放由 LDS 加载的 Account 字段
- Contacts——稍后存放 Apex 查询结果
- Columns——配置数据表格的显示
在代码中,你可以用值提供者(value provider) v. 访问属性,如 v.recordId 或 v.Account。值提供者通过把相关值封装在一起来访问数据,就像对象封装属性和方法一样。
组件还用 Lightning Data Service(force:recordData)来检索当前记录的字段并存入 Account 属性,这样就能把 Account 名称显示为组件标题。获取单条记录无需写 Apex——LDS 以声明式方式处理缓存、CRUD 和字段级安全。而 lightning:card 是一个用于显示数据的 Base Lightning Component,其标题从 v.Account.Name 动态拼接而来。
创建组件并添加到记录页(三):App Builder 放置(Create and Add an Aura Component to the Record Page (3): App Builder Placement)
现在用 Lightning App Builder 把组件放到 Account 页面上:
- 从 App Launcher 找到并打开 Accounts。
- 从 Recently Viewed 列表切换到 All Accounts,打开 United Oil & Gas Corp 这条 Account。
- 点击设置齿轮,选择 Edit Page 启动 App Builder。
- 从 Custom components 列表拖出你的组件,放到右栏顶部、Activity 组件上方。
- 点击 Save,再点击 Activate,然后点击 Assign as Org Default。
- 点击 Desktop,再点击 Next。
- 点击 Save,再点击左上角的 Back 返回记录页。
组件现在已在每个 Account 记录页上"上线"了。你会看到一个标题为 "Contact List for United Oil & Gas Corp" 的卡片——标题用表达式把 'Contact List for' 与 LDS 加载的 Account 名称拼接起来。卡片主体还是空的,因为还没添加联系人表格——但整个基础设施已经部署并正常工作了。新的 Contact List 目前为空,我们将在后续单元中添加完整功能。
检索联系人列表(03 Retrieve a Contact List)
组件有了结构,也在页面上有了位置,但卡片主体仍然为空。现在添加获取数据的逻辑:编写一个 JavaScript 控制器函数,调用 Apex 的 getContacts 方法,传入当前记录 Id,并用结果填充 Contacts 属性。
检索联系人(一):JavaScript 控制器(Retrieve the Contacts (1): JavaScript Controller)
现在添加一个事件处理器,调用 JavaScript 函数从 Salesforce 检索数据。
- 在开发者控制台中,点击 MyContactList.cmp 选项卡。
- 在右侧按钮面板点击 Controller。
- 在
myActionJavaScript 函数的函数体中,另起一行添加以下代码:
var action = component.get("c.getContacts");
action.setParams({
recordId: component.get("v.recordId")
});
action.setCallback(this, function(data) {
component.set("v.Contacts", data.getReturnValue());
});
$A.enqueueAction(action);
逐行解释:
c.getContacts——通过c(controller,服务端控制器)值提供者调用 Apex 方法v.recordId——通过v(view,视图)值提供者读取属性setParams——把 Account Id 作为参数传给 ApexsetCallback——异步处理器,在服务端响应时运行getReturnValue()——从响应对象中提取List<Contact>$A.enqueueAction——异步发送请求(非阻塞)
选择 File | Save 保存 MyContactListController.js。这个回调模式在 Aura 中普遍适用——每次服务端调用都会用到它。当 Contacts 属性变化时,组件会自动重新渲染。
检索联系人(二):事件处理器(Retrieve the Contacts (2): Event Handler)
让数据在组件首次出现在页面上时自动加载。点击 MyContactList.cmp 选项卡,在最后一个 aura:attribute 标签下方添加以下标记:
<aura:handler name="init" value="{!this}" action="{!c.myAction}" />
aura:handler 会监听特定事件,然后执行组件控制器文件中由 action 属性标识的函数:
- name="init"——组件加载到页面时触发一次的事件
- value="{!this}"——把组件实例本身传给处理器
- action="{!c.myAction}"——要执行的 JavaScript 控制器函数
完整的数据流:页面加载 → init 事件触发 → myAction() 运行 → 调用 Apex getContacts() → SOQL 返回 Contact → setCallback 存入 v.Contacts → 组件重新渲染。保存 MyContactList.cmp——组件现在是"自给自足"的了。
name="init" 的 aura:handler 相当于 Aura 里的 componentDidMount 生命周期钩子:组件首次渲染时触发一次,正是获取初始数据的最佳时机。没有它,你的 JavaScript 代码就存在但永远不会执行。
渲染并预览联系人列表(04 Render and Preview the Contact List)
数据已经在流动——Contact 被获取并存入组件属性。现在真正把它们显示出来:添加一个 lightning:datatable 基础组件,从 Contacts 属性读取数据,渲染 First Name、Last Name 和 Phone 三列。
渲染联系人列表(一):lightning:datatable(Render the Contact List (1): lightning:datatable)
点击 MyContactList.cmp 选项卡,在注释 <!-- Contact list goes here --> 之后新起一行,把占位注释替换为表格组件:
<lightning:datatable data="{! v.Contacts }" columns="{! v.Columns }"
keyField="Id" hideCheckboxColumn="true"/>
各属性作用:
- data——绑定到来自 Apex 的
Contacts列表 - columns——绑定到 JavaScript 中定义的列配置数组
- keyField——每行的唯一标识(渲染性能所必需)
- hideCheckboxColumn——移除默认的复选框列,外观更干净
保存 MyContactList.cmp。lightning:datatable 是另一个 Base Lightning Component,用来显示联系人列表。它开箱即用地处理排序、样式和响应式布局——无需自定义 CSS。基础组件是预构建、预测试、预样式化的,你无需写任何 CSS 或自行处理边界情况就能获得生产级 UI。
渲染联系人列表(二):列配置与预览(Render the Contact List (2): Columns & Preview)
点击 MyContactListController.js 选项卡,在 var action 那一行上方,更新 myAction 函数,添加列配置:
component.set("v.Columns", [
{label:"First Name", fieldName:"FirstName", type:"text"},
{label:"Last Name", fieldName:"LastName", type:"text"},
{label:"Phone", fieldName:"Phone", type:"phone"}
]);
datatable 组件用 Columns 属性中存储的值来确定要显示的列数。每个列对象定义:
- label——显示给用户的列标题文本
- fieldName——要显示的 Contact 字段 API 名
- type——数据类型(
"phone"自动格式化号码,"text"用于字符串)
最后步骤:保存 MyContactListController.js 和 MyContactList.cmp,然后刷新组织里的 Account 页面。联系人列表现在以带样式的表格渲染出来了!完整技术栈:Apex → JS → 组件 → UI。
总结(Summary)
恭喜! 你创建了第一个 Lightning 组件,端到端地从数据库走到了用户界面。现在任何管理员都可以把这个组件添加到他们的组织里,用来显示某个 Account 的联系人;其他开发者也复用它,而无需自己再写代码。
回顾这四步构建出的完整组件:
- Apex 控制器——用 SOQL 查询 Contact 的
@AuraEnabled方法(数据层) - 组件包——带属性、LDS 和
lightning:card外壳的.cmp标记 - JavaScript 控制器——异步回调调用 Apex 并存储结果
- 事件处理器——
init事件在页面打开时触发数据加载 - datatable——Base Lightning Component 渲染带格式的联系人列表
架构模式:Apex(数据)→ JavaScript(逻辑)→ 组件(UI)——这是所有 Aura 开发的基础。任何管理员都可以通过 Lightning App Builder 把你的组件拖到任何 Account 页面上,立即可用。从零到部署,四步完成。














