学习目标
完成本单元后,您将能够:
- 解释一下自定义控制器是什么,并描述其关键属性。
- 创建一个自定义控制器类。
- 在Visualforce页面上使用自定义控制器。
自定义控制器介绍
自定义控制器包含可由Visualforce页面使用的自定义逻辑和数据操作。例如,自定义控制器可以检索要显示的项目列表,向外部Web服务发出调用,验证和插入数据等等,并且所有这些操作都将可用于Visualforce页面,该页面将其用作控制器。
在其他地方介绍了Visualforce如何支持用于构建Web应用程序的模型 – 视图 – 控制器(MVC)设计模式。控制器通常检索要在Visualforce页面中显示的数据,并包含响应页面操作而执行的代码(如正在单击的按钮)。当您使用标准控制器时,平台为您提供了大量的标准功能。
但是一个尺寸并不适合所有的,并不是所有的网络应用程序都是“标准的”。当你想覆盖现有的功能,通过应用程序自定义导航,使用标注或Web服务,或者如果你需要更好地控制信息的访问方式对于您的页面,Visualforce可让您占据统治地位。您可以使用Apex编写自定义控制器,并从头到尾完全控制您的应用逻辑。
创建一个使用自定义控制器的Visualforce页面
当您的页面使用自定义控制器时,不能使用标准控制器。页面使用不同的属性来设置自定义控制器。
- 打开开发者控制台,然后点击 创建一个新的Visualforce页面。输入ContactsListController作为页面名称。
- 在编辑器中,用以下替换标记。
<apex:page controller="ContactsListController"> <apex:form> <apex:pageBlock title="Contacts List" id="contacts_list"> <!-- Contacts List goes here --> </apex:pageBlock> </apex:form> </apex:page>
创建一个自定义控制器Apex类
有许多系统和实用程序类可以帮助您编写自定义控制器逻辑,但将类用作自定义控制器的唯一要求是它存在。
- 打开开发者控制台,然后点击 创建一个新的Apex类。输入ContactsListController作为类名。
- 在编辑器中,用以下代码替换任何代码。
public class ContactsListController { // Controller code goes here }
这并不多,而且还没有做任何事情,但它确实使错误消失在Visualforce页面上。所以… - 切换回Visualforce页面并再次保存。
错误信息应该消失,页面成功保存。
- 点击预览打开您的页面的预览,您可以在进行更改时查看。
应该打开一个新窗口,显示标准的Salesforce页面标题和侧边栏元素,但没有内容。
乍一看,你创建的这两个新项目看起来并不是很有趣。但是即使它们是90%的占位符代码,Visualforce页面和Apex控制器这两个项目也是相互关联的。只要你添加更多的代码到控制器,你的页面就可以使用它。
超越基础
您可能已经注意到,这个自定义控制器类不会从另一个类继承,也不会实现一个有希望符合Visualforce控制器要求的接口。即使是复杂的控制器也不会做这些事情,因为没有任何这样的类继承或接口实现。这使您可以自由地创建自己的类和接口,随着您对Apex的经验的增加。
添加一个方法来检索记录
大多数控制器的主要目的是检索显示数据或处理数据更新。在这个简单的控制器中,您只需运行一个基本的SOQL查询来查找联系人记录,然后使这些记录可用于Visualforce页面。
- 在ContactsListController类中,用下面的代码替换// Controller代码在这里注释行。
private String sortOrder = 'LastName'; public List<Contact> getContacts() { List<Contact> results = Database.query( 'SELECT Id, FirstName, LastName, Title, Email ' + 'FROM Contact ' + 'ORDER BY ' + sortOrder + ' ASC ' + 'LIMIT 10' ); return results; }
- 在ContactsListWithController页面中,将<! – 联系人列表转到这里 – >注释行替换为以下标记。
<!-- Contacts List --> <apex:pageBlockTable value="{! contacts }" var="ct"> <apex:column value="{! ct.FirstName }"/> <apex:column value="{! ct.LastName }"/> <apex:column value="{! ct.Title }"/> <apex:column value="{! ct.Email }"/> </apex:pageBlockTable>
ContactsListWithController页面的标记应该看起来相当熟悉。除了<apex:page>标签的控制器属性之外,它与用标准控制器创建页面的代码大致相同。
不同的是当{!联系人}表达式进行评估。在此页面上,Visualforce将该表达式转换为对控制器的getContacts()方法的调用。该方法返回联系人记录列表,这正是<apex:pageBlockTable>所期望的。
getContacts()方法被称为getter方法,它是一个通用模式,其中{!您的Visualforce标记中的someExpression}将自动连接到控制器中名为getSomeExpression()的方法。这是让页面访问需要显示的数据的最简单的方法。
添加一个新的操作方法
显示数据很棒,但是对用户操作的回应对于任何网络应用程序都是至关重要的使用自定义控制器,您可以通过编写操作方法来响应用户活动,从而创建尽可能多的自定义操作,以支持页面。
- 在ContactsListController类中,getContacts()方法的下面添加以下两个方法。
public void sortByLastName() { this.sortOrder = 'LastName'; } public void sortByFirstName() { this.sortOrder = 'FirstName'; }
- 在ContactsListWithController页面中,使用以下标记替换ct.FirstName和ct.LastName的两个<apex:column>标记。
<apex:column value="{! ct.FirstName }"> <apex:facet name="header"> <apex:commandLink action="{! sortByFirstName }" reRender="contacts_list">First Name </apex:commandLink> </apex:facet> </apex:column> <apex:column value="{! ct.LastName }"> <apex:facet name="header"> <apex:commandLink action="{! sortByLastName }" reRender="contacts_list">Last Name </apex:commandLink> </apex:facet> </apex:column>
超越基础
名字和姓氏列的标题文本在这个标记中被硬编码。但是,如果你的用户不全都使用英文呢?标准Salesforce用户界面已翻译所有标准对象的字段名称版本,并且可以为自定义对象提供自己的翻译。你将如何访问这些?试试这个标记,而不是纯文本:<apex:outputText value =“{!$ ObjectType.Contact.Fields.FirstName.Label}”/>。即使您的组织使用相同的语言,这也是引用字段标签的正确方法,因为如果字段名称被更改,它将自动更新。
告诉我更多…
自定义控制器和Apex语言让您可以在Visualforce页面中完成任何您能想到的任何事情。
Getter方法将数据从您的控制器中拖出到您的页面上。有相应的setter方法可以让你从页面提交值到你的控制器。就像getter方法一样,你在setter前面加上“set”,除此之外,它们只是一个方法。
getter和setter的替代方法是使用Apex属性。属性是一种变量与getter和setter方法的组合,它们的语法可以更清楚地将它们组合在一起。引用自定义对象的简单属性可能会这样声明。
public MyObject__c myVariable { get; set; }