
关于
Salesforce 平台开发的专家模式,包括 Apex、Lightning Web Components 和平台集成。
name: salesforce-development description: Salesforce 平台开发的专家模式,包括 Lightning Web Components (LWC)、Apex 触发器和类、REST/Bulk API、Connected Apps 以及 Salesforce DX(scratch org 和第二代包 2GP)。 risk: safe source: vibeship-spawner-skills (Apache 2.0) date_added: 2026-02-27
Salesforce 开发
Salesforce 平台开发的专家模式,包括 Lightning Web Components (LWC)、Apex 触发器和类、REST/Bulk API、Connected Apps 以及 Salesforce DX(scratch org 和第二代包 2GP)。
模式
Lightning Web Component 与 Wire Service
使用 @wire 装饰器实现与 Lightning Data Service 或 Apex 方法的响应式数据绑定。@wire 适配 LWC 的响应式架构并启用 Salesforce 性能优化。
// myComponent.js
import { LightningElement, wire, api } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import getRelatedRecords from '@salesforce/apex/MyController.getRelatedRecords';
import ACCOUNT_NAME from '@salesforce/schema/Account.Name';
import ACCOUNT_INDUSTRY from '@salesforce/schema/Account.Industry';
const FIELDS = [ACCOUNT_NAME, ACCOUNT_INDUSTRY];
export default class MyComponent extends LightningElement {
@api recordId; // 从父组件或记录页面传入
// Wire 到 Lightning Data Service(单条记录首选)
@wire(getRecord, { recordId: '$recordId', fields: FIELDS })
account;
// Wire 到 Apex 方法(用于复杂查询)
@wire(getRelatedRecords, { accountId: '$recordId' })
wiredRecords({ error, data }) {
if (data) {
this.relatedRecords = data;
this.error = undefined;
} else if (error) {
this.error = error;
this.relatedRecords = undefined;
}
}
get accountName() {
return getFieldValue(this.account.data, ACCOUNT_NAME);
}
get isLoading() {
return !this.account.data && !this.account.error;
}
// 响应式:更改 recordId 会自动重新获取数据
}
<!-- myComponent.html -->
<template>
<lightning-card title={accountName}>
<template if:true={isLoading}>
<lightning-spinner alternative-text="Loading"></lightning-spinner>
</template>
<template if:true={account.data}>
<p>Industry: {industry}</p>
</template>
<template if:true={error}>
<p class="slds-text-color_error">{error.body.message}</p>
</template>
</lightning-card>
</template>
// MyController.cls
public with sharing class MyController {
@AuraEnabled(cacheable=true)
public static List<Contact> getRelatedRecords(Id accountId) {
return [
SELECT Id, Name, Email, Phone
FROM Contact
WHERE AccountId = :accountId
WITH SECURITY_ENFORCED
LIMIT 100
];
}
}
上下文
- 构建 LWC 组件
- 获取 Salesforce 数据
- 响应式 UI
批量化 Apex 触发器与 Handler 模式
Apex 触发器必须批量化以处理每个事务 200+ 条记录。使用 Handler 模式实现关注点分离、可测试性和递归防护。
// AccountTrigger.trigger
trigger AccountTrigger on Account (
before insert, before update, before delete,
after insert, after update, after delete, after undelete
) {
new AccountTriggerHandler().run();
}
// TriggerHandler.cls(基类)
public virtual class TriggerHandler {
// 递归防护
private static Set<String> executedHandlers = new Set<String>();
public void run() {
String handlerName = String.valueOf(this).split(':')[0];
// 防止递归
String contextKey = handlerName + '_' + Trigger.operationType;
if (executedHandlers.contains(contextKey)) {
return;
}
executedHandlers.add(contextKey);
switch on Trigger.operationType {
when BEFORE_INSERT { this.beforeInsert(); }
when BEFORE_UPDATE { this.beforeUpdate(); }
when BEFORE_DELETE { this.beforeDelete(); }
when AFTER_INSERT { this.afterInsert(); }
when AFTER_UPDATE { this.afterUpdate(); }
when AFTER_DELETE { this.afterDelete(); }
when AFTER_UNDELETE { this.afterUndelete(); }
}
}
// 在子类中重写
protected virtual void beforeInsert() {}
protected virtual void beforeUpdate() {}
protected virtual void beforeDelete() {}
protected virtual void afterInsert() {}
protected virtual void afterUpdate() {}
protected virtual void afterDelete() {}
protected virtual void afterUndelete() {}
}
// AccountTriggerHandler.cls
public class AccountTriggerHandler extends TriggerHandler {
private List<Account> newAccounts;
private List<Account> oldAccounts;
private Map<Id, Account> newMap;
private Map<Id, Account> oldMap;
public AccountTriggerHandler() {
this.newAccounts = (List<Account>) Trigger.new;
this.oldAccounts = (List<Account>) Trigger.old;
this.newMap = (Map<Id, Account>) Trigger.newMap;
this.oldMap = (Map<Id, Account>) Trigger.oldMap;
}
protected override void afterInsert() {
updateRelatedContacts(newAccounts);
createDefaultTeam(newAccounts);
}
protected override void afterUpdate() {
handleNameChanges(newAccounts, oldMap);
}
private void updateRelatedContacts(List<Account> accounts) {
// 批量化:收集所有需要更新的联系人
Set<Id> accountIds = new Set<Id>();
for (Account acc : accounts) {
accountIds.add(acc.Id);
}
List<Contact> contactsToUpdate = [
SELECT Id, MailingCity FROM Contact
WHERE AccountId IN :accountIds
];
// 批量更新
if (!contactsToUpdate.isEmpty()) {
update contactsToUpdate;
}
}
}
最佳实践
- 始终批量化触发器逻辑以处理大量记录
- 使用 WITH SECURITY_ENFORCED 确保字段级安全
- 在 Apex 中使用 @AuraEnabled(cacheable=true) 优化性能
- 使用 Handler 模式分离触发器逻辑
- 为所有 Apex 代码编写单元测试(覆盖率 >= 75%)
兼容工具
Claude CodeCursor
标签
前端开发