在 Lightning Web Components 成为首选之前,Visualforce 是 Salesforce 上构建自定义用户界面的框架——它用一套类 HTML 的标记语言,在服务端渲染出页面。本篇是 Trailhead「Visualforce Basics」模块的中文导读,系统讲解 Visualforce 的核心:从认识框架、在开发者控制台创建页面,到使用表达式与全局变量、标准/自定义控制器、展示记录与表格、构建输入表单、列表分页,再到引入静态资源。
全文分九个单元:第一单元认识 Visualforce 及其使用场景;第二单元在开发者控制台创建与编辑页面;第三单元用表达式和公式处理动态数据;第四单元用标准控制器读取单条记录;第五单元展示记录、字段和表格;第六单元用表单录入数据;第七单元用标准列表控制器展示和分页;第八单元引入静态资源;第九单元编写 Apex 自定义控制器。每个小节对应一页 PPT 幻灯片并附讲解视频。
01 Visualforce 入门(Get Started with Visualforce)
本单元认识 Visualforce。学完本单元,你将能够:描述 Visualforce 是什么、有什么用途,并列出三个或更多可以使用 Visualforce 的地方。
Visualforce 简介(Introduction to Visualforce)
Visualforce 是一个 Web 开发框架,让开发者能为托管在 Lightning Platform 上的移动端和桌面应用构建复杂、自定义的用户界面。你可以构建与 Lightning Experience 风格一致的应用,也可以打造完全自定义的界面。
开发者可以扩展 Salesforce 的内置功能、用新功能替换它们,甚至构建全新的应用;既可使用强大的内置标准控制器,也可用 Apex 编写自己的业务逻辑。
对任何做过 Web 开发的人来说都很熟悉:页面由组件、HTML 和可选的样式组成,每个页面都有一个唯一 URL 访问。当有人访问页面时,服务器执行页面所需的数据处理,把页面渲染成 HTML,再把结果返回给浏览器。
一个 Visualforce 页面示例(An Example Visualforce Page)
下面是一个简短的工作示例:一个联系人数据录入表单,只用十几行标记就完成了大量工作。
- 它连接到 Visualforce 标准控制器——框架中提供自动数据访问、修改和标准动作的部分。
- 不带记录 ID 访问时,页面显示空白表单;点击 Save 会从表单数据创建一条新记录。
- 带记录 ID 访问时,页面查出该联系人记录并显示为可编辑表单;点击 Save 会把更改保存回数据库。
- 每个输入字段都很"聪明":邮箱字段能识别合法邮箱、日期字段会弹出日期选择器,Save 按钮则调用标准控制器提供的标准动作。
从应用启动器打开 Visualforce 页面(Open a Visualforce Page from the App Launcher)
你的 Visualforce 应用和自定义选项卡都可以从应用启动器(App Launcher)访问。
- 点击导航栏中的 App Launcher 图标。
- 选择 View All 查看所有应用和项目。
- 点击一个自定义应用将其激活。
应用中的项目(包括你添加的任何 Visualforce 选项卡)会显示在导航栏中。注意:你需要把 Visualforce 页面添加到选项卡中,它们才会出现在 App Launcher 里;不在任何应用中的 Visualforce 选项卡可以在 All Items 下找到。
把 Visualforce 页面添加到导航栏(Add a Visualforce Page to the Navigation Bar)
把 Visualforce 选项卡添加到一个应用后,它们就会作为项目显示在该应用的导航栏中。这样用户就能从他们已经在使用的应用里,一键访问你的 Visualforce 页面。
在标准页面布局中显示 Visualforce 页面(Display a Visualforce Page within a Standard Page Layout)
你可以把 Visualforce 页面嵌入页面布局,从而在标准页面上显示完全自定义的内容。这里的行为与 Salesforce Classic 完全相同——只是在 Lightning Experience 中,你需要查看记录的 Details 才能看到页面布局部分。
在 Lightning App Builder 中添加 Visualforce 页面组件(Add a Visualforce Page as a Component in the Lightning App Builder)
当你在 Lightning App Builder 中创建自定义应用页面时,可以通过 Visualforce 组件把 Visualforce 页面拖入其中。要注意的是,为了让它可用,你必须在 Visualforce 页面上启用 「Available for Lightning Experience, Lightning Communities, and the mobile app」 设置。
把 Visualforce 页面作为快速操作启动(Launch a Visualforce Page as a Quick Action)
你可以把 Visualforce 页面作为快速操作(quick action)启动。虽然它在 Lightning Experience 中的位置与 Salesforce Classic 差异很大,但添加快速操作的过程基本相同——把它加到对象页面布局上合适的发布区域(publisher area)。
通过覆盖标准按钮或链接显示 Visualforce 页面(Display a Visualforce Page by Overriding Standard Buttons or Links)
你可以用 Visualforce 页面覆盖对象上的动作:当用户点击被覆盖的按钮或链接时,显示的是你的页面而不是标准页面。这个设置几乎与 Salesforce Classic 完全相同——事实上,定义动作覆盖时,你几乎察觉不到自己正身处 Lightning Experience。
使用自定义按钮或链接显示 Visualforce 页面(Display a Visualforce Page Using Custom Buttons or Links)
你可以为对象创建新的动作,形式为按钮和链接,直接在对象上定义。JavaScript 按钮和链接在 Lightning Experience 中不受支持,但 Visualforce(以及 URL)项目是受支持的。定义 Visualforce 按钮和链接的过程与 Salesforce Classic 完全相同。
02 创建与编辑 Visualforce 页面(Create & Edit Visualforce Pages)
本单元学习创建和编辑页面。学完本单元,你将能够:解释什么是 Visualforce 页面及其关键属性、列出并打开组织中已有的页面、用开发者控制台创建和编辑页面,并在编辑器中识别、添加和自定义标签与属性。
Visualforce 页面简介(Introduction to Visualforce Pages)
Visualforce 页面是应用开发者的基本构建块。它类似标准网页,但拥有访问、显示和更新组织数据的强大能力,可通过唯一 URL 引用和调用。
Visualforce 使用与 HTML 类似的基于标签的标记语言:每个标签对应一个 UI 组件(页面区块、列表视图或字段),有近 150 个内置组件,还可以创建自己的组件。Visualforce 标记可以自由地与 HTML、CSS 和 JavaScript 混用。
在开发者控制台创建 Visualforce 页面(Create Visualforce Pages in the Developer Console)
开发者控制台(Developer Console)是处理页面的最佳内置工具,提供语法高亮、标签配对、自动建议/自动补全、智能缩进等功能。
- 打开开发者控制台(在 Your Name / 快捷访问菜单下)。
- 点击 File | New | Visualforce Page。
- 命名为 HelloWorld,点击 OK。
- 输入标记:
<apex:page><h1>Hello World</h1></apex:page>。 - File | Save,然后点击 Preview 预览。
注意,预览不包含 Salesforce 样式。要在 Lightning Experience 中查看,可以在浏览器控制台触发 navigateToURL 事件(等价于访问 /apex/PageName)。用 File | Open 可以列出并打开已有的页面。
使用自动建议添加属性(Add Attributes Using Auto-Suggest)
属性可以自定义组件的行为,用自动建议(auto-suggest)添加它们很方便:
- 在
<apex:page>开始标签内、>之前,输入一个空格再输入s。 - 随着输入,建议逐渐收窄;选择
sidebar并回车。 - 选择
false→ 得到<apex:page sidebar="false">。 - 重复上述步骤添加
showHeader="false"。 - 保存。
自动建议在你已经熟悉组件时非常高效;而在学习阶段,建议常备 Standard Component Reference 参考。
进阶(一):页面属性的行为(Beyond the Basics: How Page Attributes Behave)
有一个值得了解的行为:在 Salesforce Classic 中,sidebar 和 showHeader 默认值为 true;但在 Lightning Experience 和 Salesforce 移动应用中,它们的值被覆盖、始终为 false,且无法抑制 Lightning Experience 的页头。页面仍会包含部分 Salesforce 样式表以匹配字体和字号;要抑制所有 Salesforce 输出,可添加 standardStylesheets="false"。
进阶(二):组合组件构建结构(Beyond the Basics: Compose Components for Structure)
添加并组合组件来形成页面结构:
- 添加
<apex:pageBlock title="A Block Title">——一个分组 UI 元素。 - 在它内部添加
<apex:pageBlockSection title="A Section Title">——可折叠、增加层级。 - 在区块内放入文本(如
I'm three components deep!)。 - 再添加一个
pageBlockSection承载更多内容。
规则:pageBlockSection 必须嵌套在 pageBlock 内;子 pageBlockSection 不能脱离父 pageBlock 存在。
03 使用简单变量和公式(Use Simple Variables and Formulas)
本单元学习表达式和动态数据。学完本单元,你将能够:解释什么是 Visualforce 表达式、列出三个或更多全局变量、在页面中使用函数,并用条件表达式显示动态内容。
全局变量(Global Variables)
Visualforce 页面通过全局变量、计算和控制器属性访问动态数据,合称 Visualforce 表达式。语法为 {! expression }:分隔符内的内容在页面渲染时被求值并动态替换,忽略空白、大小写不敏感。
例如 $User 提供当前登录用户的信息:{!$User.FirstName} {!$User.LastName} ({!$User.Username})。结果可以是原始类型、布尔值、sObject 或方法结果;但方法调用不允许出现在表达式中。
公式表达式(Formula Expressions)
表达式语言还支持公式来操作值:
- 用
&拼接字符串:{!$User.FirstName & ' ' & $User.LastName}。 - 日期函数:
{! TODAY() }返回当前日期,{! TODAY() + 7 }加七天。 - 函数是内置计算,通过名称后的括号识别:
TODAY()无参数、YEAR(TODAY())接受日期、MAX()接受任意数量参数、CONTAINS('salesforce.com','force.com')返回布尔值true。
条件表达式(Conditional Expressions)
用条件表达式根据值显示不同信息。例如发票没有行项目时显示 "none",或条目过期时显示 "Ended"。IF() 接受三个参数:布尔条件、为真时返回的值、为假时返回的值。
{! IF(CONTAINS('salesforce.com','force.com'), 'Yep', 'Nope') }{! IF(DAY(TODAY()) < 15, 'Before the 15th', 'The 15th or after') }
更实用的例子:$User.isActive 是布尔字段,可写成 IF($User.isActive, $User.Username, 'inactive'),用户活跃时显示用户名,停用时显示 "inactive"。
04 使用标准控制器(Use Standard Controllers)
本单元学习 MVC 与标准控制器。学完本单元,你将能够:解释标准控制器及其关键属性、给页面添加标准控制器、通过 URL 传入记录 ID 显示数据,并用点号访问关联记录的字段。
Visualforce 标准控制器简介(Introduction to the Visualforce Standard Controller)
Visualforce 使用传统的 MVC 范式:模型(Model)是数据库,视图(View)是你的页面,控制器(Controller)提供功能。内置的标准控制器处理标准动作和数据访问,与 Lightning Platform 数据库紧密集成。大多数标准对象和所有自定义对象都有标准控制器,无需自己编写代码;你也可以扩展它们,或用 Apex 从头编写自定义控制器。
查找记录 ID 并添加到请求 URL(Find a Record ID and Add It to the Request URL)
标准控制器需要记录的 ID 来加载和保存该记录。开发期间页面是独立的,所以需要手动把 ID 作为 GET 参数加到 URL 中。
- 打开 Accounts 选项卡,确认 View 显示 All Accounts。
- 点击任意账户名,从 URL 读取记录 ID(形如
001D000000JRBes)。 - 回到开发者控制台预览,在 URL 末尾追加
&id=001D000000JRBes并重新加载。
加上 ID 后,控制器就能加载该记录并让它对页面可用。
显示单条记录的数据(Display Data from a Single Record)
给 <apex:page> 标签添加 standardController="Account";页面加载时,控制器解析 URL 找到 id 参数并检索该记录。然后用点号在 Account 变量上显示字段:
Name: {! Account.Name }<br/>、Phone: {! Account.Phone }、Industry: {! Account.Industry }、Revenue: {! Account.AnnualRevenue }。
控制器把记录放进一个与 sObject 同名的变量(Account),表达式引用其字段。注意:原始数字(如年收入)会以科学计数法显示,需要组件来格式化。
显示关联记录中的字段(Display Fields from Related Records)
用点号遍历关系。Account 对象有一个 Account Owner 字段,类型为 Lookup(User),字段名是 Owner。由于 Owner 表示一个 User 记录,而 User 有 Name 字段,所以可以这样显示所有者的名字:
{! Account.Owner.Name }——Account.Owner 是账户的 Owner 字段,额外的 .Name 顺着查找关系进入关联的 User 记录并读取其 Name 字段。
了解更多(标准控制器)(Tell Me More: Standard Controllers)
标准控制器很强大:
- 标准动作:create、edit、save、delete 等,可用按钮和链接添加到页面。
- 要求:嵌入页面布局、用作对象特定动作或移动卡片的页面,必须使用相应对象的标准控制器。
- 自定义字段:用 API 名引用,如
{! myobject__c.foo__c }(标准字段不带__c)。
任何时候都可以用 Apex 编写自己的控制器或扩展来替换或增强标准控制器。
05 显示记录、字段和表格(Display Records, Fields, and Tables)
本单元学习输出组件。学完本单元,你将能够:区分粗粒度与细粒度组件、解释迭代组件,并用合适的组件显示记录详情、相关列表、单个字段和表格。
用标准控制器创建 Visualforce 页面(Create a Visualforce Page with a Standard Controller)
先创建一个名为 AccountDetail 的页面,加上 Account 标准控制器和一个表达式 {! Account.Name }:
<apex:page standardController="Account">{! Account.Name }</apex:page>
预览并把账户 ID 加到 URL(?id=...);当正文中出现账户名时,就确认了标准控制器与有效记录 ID 正常工作。
显示记录详情(Display Record Details)
用 <apex:detail /> 快速添加记录详情。把 {! Account.Name } 替换成 <apex:detail />,保存、预览、加上记录 ID——一行标记就重现了该对象整个标准视图页!
apex:detail 是粗粒度组件,添加大量字段、区块、按钮和 UI 元素,且使用 Salesforce Classic 样式;它有多个可自定义的属性。要创建与 Lightning Experience 风格对齐的页面,可参考 Visualforce & Lightning Experience 模块。
显示相关列表(Display Related Lists)
用 <apex:relatedList> 显示与当前记录相关的记录列表——比如账户的联系人、案例、商机等,并渲染成带表头和每行一条记录的表。
apex:detail 可以用 relatedList="false" 隐藏所有相关列表,再用 apex:relatedList 逐个加回你需要的。它比 apex:detail 更底层:detail 一次显示许多列表,relatedList 让你逐个配置。规则是:高阶组件满足需求就用高阶,需要更多控制时用低阶。
显示单个字段(Display Individual Fields)
需要更精确布局控制时,用 <apex:outputField> 逐个添加字段。单独使用时它只输出字段值(一行、无标签、无样式);但把它包在 pageBlock/pageBlockSection 里,行为就变了——采用两列布局、添加字段标签并对齐样式,年收入还会自动格式化为货币。
outputField 其实很智能:它会根据字段的数据类型自动适配格式(日期、复选、下拉等都能正确处理)。
显示表格(Display a Table)
用 <apex:pageBlockTable> 添加数据表格。它是一个迭代组件,作用于集合(如 {!Account.contacts})而非单个值:
<apex:pageBlockTable value="{!Account.contacts}" var="contact">,内部用 <apex:column value="{!contact.Name}"/> 等定义列。
工作原理:value 是记录列表,var 是当前记录的变量,每个 apex:column 提取一个字段,表头来自字段标签。其他迭代组件还有 apex:dataTable、apex:dataList、apex:repeat。
06 用表单录入数据(Input Data Using Forms)
本单元构建表单。学完本单元,你将能够:解释表单的基本要求、区分带平台样式的表单元素、列出四个以上输入标签,并创建编辑保存记录的表单。
Visualforce 表单简介(Introduction to Visualforce Forms)
创建和编辑数据是任何应用的基本能力。Visualforce 把标准控制器与 <apex:form> 组件和简单的表单元素结合,即可构建相当复杂的记录编辑页。
一个编辑记录的页面需要:查出记录、把数据显示在编辑表单中、接收提交的更改、校验新值、保存有效更改,并显示成功或错误消息——使用标准控制器和 apex:form 时,Visualforce 会自动完成其中大部分工作。
创建基本表单(Create a Basic Form)
组合 apex:form + apex:inputField + apex:commandButton 来编辑和保存:
<apex:page standardController="Account"> 里放 <apex:form>,内含 <apex:inputField value="{! Account.Name }"/> 和 <apex:commandButton action="{! save }" value="Save" />。
要点:标准控制器提供数据访问;apex:form 把内容打包用于一次页面动作(把数据发回);apex:inputField 渲染字段对应的输入控件;apex:commandButton 的 action="{!save}" 调用控制器的保存动作。几行代码就是一个可用的编辑表单。
添加字段标签和平台样式(Add Field Labels and Platform Styling)
把表单元素包进 apex:pageBlock 和 apex:pageBlockSection 以采用平台视觉样式(标签、布局、样式)。再添加电话、行业、年收入等字段。
apex:inputField 会根据字段类型渲染合适的控件:日期字段显示日历控件,行业这类下拉字段显示下拉列表。它对标准或自定义字段都适用,并尊重字段的元数据——是否必填、是否唯一,以及当前用户是否有查看/编辑权限。
显示表单错误和消息(Display Form Errors and Messages)
出错时要给用户有用的反馈,标准控制器会处理这些,你只需指定消息显示的位置:
- 在 pageBlock 下添加
<apex:pageMessages/>。 - 试试删除账户名后保存。
结果:inputField 在自己的字段上显示错误,而 pageMessages 在页面顶部把所有错误集中列出——这对长表单很友好。控制器在表单处理时收集消息,pageMessages 只是在你选择的位置显示它们。
编辑关联记录(Edit Related Records)
用标准控制器无法在单次请求中保存多种对象类型,但你可以提供链接让用户方便地导航到关联记录。在 pageBlockTable 中列出账户的联系人,一列 apex:outputLink 用 URLFOR() + $Action 全局变量 + 联系人 ID 生成 Edit 和 Del 链接,点击即可跳转到该联系人的编辑页。
了解更多(Visualforce 表单)(Tell Me More: Visualforce Forms)
关于表单还有更多:
- 输入组件:除
inputField外还有十来个,名字多以apex:input开头;选择列表和单选按钮用apex:select*;移动端可用支持 HTML5 的apex:input。 - 标准动作:控制器内置的 create、edit、save 等,部分对象还有更多。
- 创建新的关联记录较难:编辑/删除作用于已有关联记录,创建则需要自己建立关系,需自定义控制器代码。
07 使用标准列表控制器(Use Standard List Controllers)
本单元展示记录列表。学完本单元,你将能够:解释标准列表控制器与标准(记录)控制器的区别、显示记录列表、添加列表视图筛选和分页。
显示记录列表(Display a List of Records)
标准列表控制器加载一组记录(而非单条)。在 <apex:page> 上设两个属性:standardController="Contact" 和 recordSetVar="contacts"(约定用对象名的复数)。然后用 apex:pageBlockTable value="{! contacts }" var="ct" 加列(ct.FirstName 等)显示。
给列表添加列表视图筛选(Add List View Filtering to the List)
标准列表控制器允许使用任何声明式创建的列表视图筛选器。因为切换筛选器要提交回服务器,先给 pageBlock 包一层 apex:form,再给它加 id="contacts_list"(作为 Ajax 刷新目标),最后在表格上方加筛选控件:
<apex:selectList value="{! filterId }" size="1"> 内含 <apex:selectOptions value="{! listViewOptions }"/> 和 <apex:actionSupport event="onchange" reRender="contacts_list"/>。
两个效果:选择筛选器会改变列表;reRender 只通过 Ajax 更新那个 pageBlock,不整页刷新。listViewOptions 和 filterId 来自标准列表控制器。
给列表添加分页(Add Pagination to the List)
长列表需要分页。标准列表控制器默认只显示前 20 条匹配记录。分页控件包括:
- 进度:用
PageNumber、ResultSize、PageSize显示 Page X of Y。 - 上一页/下一页链接:
<apex:commandLink action="{! Previous }" rendered="{! HasPrevious }"/>(禁用时用灰色outputText显示)。 - 每页记录数菜单:用
apex:selectList设置{! PageSize }。
rendered="{! 布尔值 }" 是 Visualforce 按条件显示/隐藏组件的方式。
08 使用静态资源(Use Static Resources)
本单元学习静态资源。学完本单元,你将能够:解释什么是静态资源及用途、区分单个与压缩静态资源,创建上传静态资源并添加到页面。
创建并上传简单静态资源(Create and Upload a Simple Static Resource)
静态资源让你上传页面可引用的内容——归档、图片、样式表、JavaScript 等。Lightning Platform 像 CDN 一样管理和分发它们,缓存和分发自动处理。
- 下载 jQuery 库。
- Setup 快速查找 Static Resources → New。
- 命名 jQuery。
- Choose File 选择 jQuery 文件。
- Cache Control 选 Public(如出现)。
- 保存。
然后用 {! $Resource.jQuery } 引用它。好处是:升级资源(如新版本 jQuery)无需改动页面。
把静态资源添加到 Visualforce 页面(Add a Static Resource to a Visualforce Page)
用 $Resource 全局变量加点号在对应的包含标签里引用:<apex:includeScript value="{!$Resource.jQuery }"/> 引入 JavaScript;apex:stylesheet 引入 CSS;apex:image 引入图形。页面里写一小段 jQuery 脚本,如设置 #message 的内容为 "Hello from jQuery!" 来验证资源已加载。
创建并上传压缩静态资源(Create and Upload a Zipped Static Resource)
当静态资源是一组相关文件(如一组图标或复杂 JS 库)时,创建压缩(zipped)静态资源:下载 jQuery Mobile 的 ZIP,移除 /demos/ 目录,重新压缩并命名为 jquery.zip,在 Setup 中新建静态资源命名为 jQueryMobile 并上传该 zip。你上传一个 zip 文件,之后再引用其中的单个文件。
把压缩静态资源添加到 Visualforce 页面(Add Zipped Static Resources to a Visualforce Page)
用 $Resource + URLFOR() 引用压缩资源内的项目:URLFOR($Resource.jQueryMobile, 'images/icons-png/cloud-black.png') 返回 zip 内某个图形的 URL,可交给 apex:image;JavaScript 和样式表也同理配合 includeScript 和 stylesheet。注意示例使用 jQuery Mobile 1.4.5,用新版时要更新版本号。
09 创建与使用自定义控制器(Create & Use Custom Controllers)
本单元编写 Apex 驱动页面。学完本单元,你将能够:解释自定义控制器及其关键属性、创建自定义控制器类,并在页面中使用它。
自定义控制器简介(Introduction to Custom Controllers)
在 <apex:page> 的 controller 属性里引用控制器类名即可添加自定义控制器:<apex:page controller="ContactsListWithController">。注意:使用自定义控制器就不能再使用标准控制器(二者互斥)。保存页面时会报错,因为 Apex 类还不存在——下一步就创建它。
创建自定义控制器 Apex 类(Create a Custom Controller Apex Class)
自定义控制器只是一个你自己写的 Apex 类:在开发者控制台 File | New | Apex Class 新建,命名 ContactsListWithController 并保存。一个类能被用作自定义控制器的唯一要求是它存在——保存后页面报错消失,页面与控制器就此链接起来,之后向控制器添加代码页面就能使用。
进阶(一):无需继承(Beyond the Basics: No Inheritance Needed)
注意这个自定义控制器类不继承其他类,也不实现任何控制器接口——即便是复杂的控制器也一样,因为根本没有可继承的类或可实现的接口。这种自由让你能随着 Apex 经验的增长创建自己的类和接口。
添加检索记录的方法(一):Getter(Add a Method to Retrieve Records: The Getter)
添加一个运行 SOQL 查询的 getter 方法:私有变量 sortOrder = 'LastName',公共方法 getContacts() 用 Database.query(...) 查询并按 sortOrder 排序返回联系人列表。页面上 {! contacts } 会自动映射到控制器的 getContacts() 方法——这就是 getter 模式:{! someExpression } 连接 getSomeExpression()。
添加检索记录的方法(二):排序的动作方法(Add a Method to Retrieve Records: Action Methods to Sort)
响应用户输入用动作方法:写 sortByLastName() 和 sortByFirstName() 修改 sortOrder。要让表头可点击,用 <apex:facet name="header"> 包裹 <apex:commandLink action="{! sortByLastName }" reRender="contacts_list">。点击表头触发动作、改变 sortOrder,表格重渲染并重新查询,列表按新顺序排序。注意动作方法与引用它们的表达式同名(与 getter 不同)。
进阶(二):翻译的字段标签(Beyond the Basics: Translated Field Labels)
这里的表头是硬编码英文。若用户并非都用英语,应引用字段的标签:<apex:outputText value="{! $ObjectType.Contact.Fields.FirstName.Label }"/>。即便组织里所有人都用同一种语言,这也是正确做法——字段名一旦更改,标签会自动更新。
了解更多(自定义控制器)(Tell Me More: Custom Controllers)
自定义控制器 + Apex 几乎可以在页面里做任何事:
- Getter 方法把数据拉到页面;对应的 setter 方法(前缀
set)把值从页面提交回控制器。 - Apex 属性把变量与 getter/setter 组合,可 public/private、只读或只写。
- Apex 是一门完整语言,在 Visualforce 之外也广泛使用。
重要提醒:getter/setter/property 的调用没有固定顺序,切勿在它们之间引入执行顺序依赖。























































