Visualforce-邮件模板(2)样式

默认情况下,Visualforce电子邮件模板始终使用其他Salesforce组件的标准外观。但是,您可以通过定义自己的样式表来扩展或覆盖这些样式。
与其他Visualforce页面不同,Visualforce电子邮件模板不能使用引用的页面样式或静态资源。尽管CSS似乎在电子邮件模板预览窗格中呈现,但它与您的电子邮件的收件人不同。您必须在<style>标签内使用CSS定义您的样式。
以下示例将电子邮件的字体更改为Courier,将边框添加到表中,并更改表格行的颜色:

<messaging:emailTemplate recipientType=”Contact”
relatedToType=”Account”
subject=”Case report for Account: {!relatedTo.name}”
replyTo=”support@acme.com”>
<messaging:htmlEmailBody>
<html>
<style type=”text/css”>
body {font-family: Courier; size: 12pt;}
table {
border-width: 5px;
border-spacing: 5px;
border-style: dashed;
border-color: #FF0000;
background-color: #FFFFFF;
}
td {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #000000;
background-color: #FFEECC;
}
th {
color: #000000;
border-width: 1px ;
padding: 4px ;
border-style: solid ;
border-color: #000000;
background-color: #FFFFF0;
}
</style>
<body>
<p>Dear {!recipient.name},</p>
<table border=”0″ >
<tr>
<th>Case Number</th><th>Origin</th>
<th>Creator Email</th><th>Status</th>
</tr>
<apex:repeat var=”cx” value=”{!relatedTo.Cases}”>
<tr>
<td><a href =
“https://na1.salesforce.com/{!cx.id}”>{!cx.CaseNumber}
</a></td>
<td>{!cx.Origin}</td>
<td>{!cx.Contact.email}</td>
<td>{!cx.Status}</td>
</tr>
</apex:repeat>
</table>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>

在自定义组件中定义Visualforce样式表

虽然您无法在Visualforce电子邮件模板中引用外部样式表,但您可以将样式定义放置在可在其他位置引用的自定义组件中。例如,您可以修改前面的示例以将样式信息放入名为EmailStyle的组件中:

<apex:component access=”global”>
<style type=”text/css”>
body {font-family: Courier; size: 12pt;}
table {
border-width: 5px;
border-spacing: 5px;
border-style: dashed;
border-color: #FF0000;
background-color: #FFFFFF;
}
td {
border-width: 1px;
padding: 4px;
border-style: solid;
border-color: #000000;
background-color: #FFEECC;
}
th {
color: #000000;
border-width: 1px ;
padding: 4px ;
border-style: solid ;
border-color: #000000;
background-color: #FFFFF0;
}
</style>
</apex:component>

然后,在Visualforce电子邮件模板中,您只能引用该组件:

<messaging:htmlEmailBody>
<html>
<c:EmailStyle />
<body>
<p>Dear {!recipient.name},</p>

</body>
</html>
</messaging:htmlEmailBody>

注意:在Visualforce电子邮件模板中使用的任何<apex:component>标记都必须具有全局访问级别。

Visualforce-邮件模板(1)创建

开发人员和管理员可以使用Visualforce创建电子邮件模板。使用Visualforce超过标准HTML的优势电子邮件模板是Visualforce使您能够对发送给收件人的数据执行高级操作。
虽然Visualforce电子邮件模板使用标准的Visualforce组件,但它们不是以相同的方式创建的。 Visualforce电子邮件模板始终使用以消息传递名称空间开头的组件。此外:

  • 所有Visualforce电子邮件模板必须包含在一个<messaging:emailTemplate>标记中。这与在单个<apex:page>标签中定义的常规Visualforce页面类似。
  • <messaging:emailTemplate>标记必须包含单个<messaging:htmlEmailBody>标记或单个<messaging:plainTextEmailBody>标记。
  • 几个标准的Visualforce组件在<messaging:emailTemplate>中不可用。这些包括<apex:detail>,<apex:pageBlock>和所有相关的pageBlock组件以及所有输入组件,如<apex:form>。如果您尝试使用这些组件保存Visualforce电子邮件模板,则会显示一条错误消息。

创建一个Visualforce电子邮件模板

  1. 执行以下操作之一:
    • 如果您有权编辑公共模板,请从“设置”中,在快速查找方框中输入电子邮件模板,然后选择电子邮件模板。
    • 如果您无权修改公共模板,请转到个人设置。在快速查找框中输入模板,然后选择电子邮件模板或我的模板 – 无论哪一个出现。
  2. 点击 New Template.
  3. 选择 Visualforce 然后单击 Next.
    您无法使用Visualforce电子邮件模板发送群发电子邮件。
  4. 选择一个文件夹来存储模板。
  5. 要使模板可供使用,请选择可用的复选框。
  6. 在电子邮件模板名称中输入名称。
  7. 如有必要,请更改模板唯一名称。这个唯一的名称是指使用Force.com API时的组件。在托管包中,此唯一名称可防止程序包安装中的命名冲突。此名称只能包含下划线和字母数字字符,并且在您的组织中必须是唯一的。它必须以字母开头,不能包含空格,不能以下划线结尾,并且不要包含两个连续的下划线。使用“模板唯一名称”字段,可以更改托管数据包中某些组件的名称,这些更改将反映在订户组织中。
  8. 如果需要,请从编码下拉列表中选择不同的字符集。
  9. 输入模板的描述。模板名称和说明仅供您内部使用。
  10. 在电子邮件主题中输入您的模板的主题行。
  11. 在“收件人类型”下拉列表中,选择要从模板创建的收件人的类型。
  12. 如果需要,请在相关类型下拉列表中选择模板检索合并字段数据的对象。
  13. 点击 Save.
  14. 在Salesforce Classic页面的查看电子邮件模板中,单击编辑模板。
  15. 为您的Visualforce电子邮件模板输入标记文本。
    注意:如果您正在添加图片,我们建议将其上传到“文档”选项卡,以引用服务器上的图像副本。例如:
    <apex:image id=”Logo”
    value=”https://yourInstance.salesforce.com/servlet/servlet.ImageServer?
    id=015D0000000Dpwc&oid=00DD0000000FHaG&lastMod=127057656800″ />
  16. 要指定Visualforce的版本以及此电子邮件模板使用的API,请单击版本设置。如果您已经通过AppExchange安装了托管软件包,则还可以指定每个托管软件包的哪个版本与此电子邮件模板配合使用。通常,使用所有版本的默认值,将电子邮件模板与最新版本的Visualforce,API和每个托管软件包相关联。要保持特定的行为,您可以指定较旧版本的Visualforce和API。要访问与最新软件包版本不同的组件或功能,可以指定旧版本的托管软件包。
  17. 要查看模板的详细信息,请单击保存。要继续编辑您的模板,请点击快速保存。在保存模板之前,您的Visualforce标记必须有效。

注意:

Visualforce电子邮件模板的最大大小为1 MB。
您无法使用Visualforce电子邮件模板发送群发电子邮件。 {!Receiving_User.field_name}和
{!Sending_User.field_name}合并字段仅适用于海量电子邮件和列表电子邮件,并且在Visualforce电子邮件模板中不可用。

以下示例显示如何定义显示与联系人关联的所有情况的Visualforce电子邮件模板。 该示例使用<apex:repeat>标签遍历与联系人有关的所有情况,并将它们合并到主体中
模板:

<messaging:emailTemplate recipientType=”Contact”
relatedToType=”Account”
subject=”Case report for Account: {!relatedTo.name}”
language=”{!recipient.Languages__c}”
replyTo=”support@acme.com”>
<messaging:htmlEmailBody>
<html>
<body>
<p>Dear {!recipient.name},</p>
<p>Below is a list of cases related to {!relatedTo.name}.</p>
<table border=”0″ >
<tr>
<th>Case Number</th><th>Origin</th>
<th>Creator Email</th><th>Status</th>
</tr>
<apex:repeat var=”cx” value=”{!relatedTo.Cases}”>
<tr>
<td><a href =
“https://yourInstance.salesforce.com/{!cx.id}”>{!cx.CaseNumber}
</a></td>
<td>{!cx.Origin}</td>
<td>{!cx.Contact.email}</td>
<td>{!cx.Status}</td>
</tr>
</apex:repeat>
</table>
<p/>
<center>
<apex:outputLink value=”http://www.salesforce.com”>
For more detailed information login to Salesforce.com
</apex:outputLink>
</center>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>

注意以下关于标记:

  • recipientType和relatedToType属性充当电子邮件模板的控制器。有了它们,您可以访问其他标准控制器可用的相同合并字段。 recipientType属性表示电子邮件的收件人。 relatedToType属性表示与电子邮件关联的记录。 
  • <messaging:htmlEmailBody>组件可以包含Visualforce标记和HTML的组合。 <messaging:plainTextEmailBody>组件只能包含Visualforce标记和纯文本。 
  • 要根据收件人或相关对象的语言翻译Visualforce电子邮件模板,请使用
    <messaging:emailTemplate>标签的语言属性(有效值:Salesforce支持的语言键,例如“en-US”)。 language属性接受来自电子邮件模板的recipientType和relatedToType属性的合并字段。您可以创建用于合并字段的自定义语言字段。翻译工作台需要翻译电子邮件模板。该示例使用合并字段为接收电子邮件的联系人获取语言属性。

Visualforce-邮件模板(1)创建

开发人员和管理员可以使用Visualforce创建电子邮件模板。使用Visualforce超过标准HTML的优势电子邮件模板是Visualforce使您能够对发送给收件人的数据执行高级操作。
虽然Visualforce电子邮件模板使用标准的Visualforce组件,但它们不是以相同的方式创建的。 Visualforce电子邮件模板始终使用以消息传递名称空间开头的组件。此外:

  • 所有Visualforce电子邮件模板必须包含在一个<messaging:emailTemplate>标记中。这与在单个<apex:page>标签中定义的常规Visualforce页面类似。
  • <messaging:emailTemplate>标记必须包含单个<messaging:htmlEmailBody>标记或单个<messaging:plainTextEmailBody>标记。
  • 几个标准的Visualforce组件在<messaging:emailTemplate>中不可用。这些包括<apex:detail>,<apex:pageBlock>和所有相关的pageBlock组件以及所有输入组件,如<apex:form>。如果您尝试使用这些组件保存Visualforce电子邮件模板,则会显示一条错误消息。

创建一个Visualforce电子邮件模板

  1. 执行以下操作之一:
    • 如果您有权编辑公共模板,请从“设置”中,在快速查找方框中输入电子邮件模板,然后选择电子邮件模板。
    • 如果您无权修改公共模板,请转到个人设置。在快速查找框中输入模板,然后选择电子邮件模板或我的模板 – 无论哪一个出现。
  2. 点击 New Template.
  3. 选择 Visualforce 然后单击 Next.
    您无法使用Visualforce电子邮件模板发送群发电子邮件。
  4. 选择一个文件夹来存储模板。
  5. 要使模板可供使用,请选择可用的复选框。
  6. 在电子邮件模板名称中输入名称。
  7. 如有必要,请更改模板唯一名称。这个唯一的名称是指使用Force.com API时的组件。在托管包中,此唯一名称可防止程序包安装中的命名冲突。此名称只能包含下划线和字母数字字符,并且在您的组织中必须是唯一的。它必须以字母开头,不能包含空格,不能以下划线结尾,并且不要包含两个连续的下划线。使用“模板唯一名称”字段,可以更改托管数据包中某些组件的名称,这些更改将反映在订户组织中。
  8. 如果需要,请从编码下拉列表中选择不同的字符集。
  9. 输入模板的描述。模板名称和说明仅供您内部使用。
  10. 在电子邮件主题中输入您的模板的主题行。
  11. 在“收件人类型”下拉列表中,选择要从模板创建的收件人的类型。
  12. 如果需要,请在相关类型下拉列表中选择模板检索合并字段数据的对象。
  13. 点击 Save.
  14. 在Salesforce Classic页面的查看电子邮件模板中,单击编辑模板。
  15. 为您的Visualforce电子邮件模板输入标记文本。
    注意:如果您正在添加图片,我们建议将其上传到“文档”选项卡,以引用服务器上的图像副本。例如:
    <apex:image id=”Logo”
    value=”https://yourInstance.salesforce.com/servlet/servlet.ImageServer?
    id=015D0000000Dpwc&oid=00DD0000000FHaG&lastMod=127057656800″ />
  16. 要指定Visualforce的版本以及此电子邮件模板使用的API,请单击版本设置。如果您已经通过AppExchange安装了托管软件包,则还可以指定每个托管软件包的哪个版本与此电子邮件模板配合使用。通常,使用所有版本的默认值,将电子邮件模板与最新版本的Visualforce,API和每个托管软件包相关联。要保持特定的行为,您可以指定较旧版本的Visualforce和API。要访问与最新软件包版本不同的组件或功能,可以指定旧版本的托管软件包。
  17. 要查看模板的详细信息,请单击保存。要继续编辑您的模板,请点击快速保存。在保存模板之前,您的Visualforce标记必须有效。

注意:

Visualforce电子邮件模板的最大大小为1 MB。
您无法使用Visualforce电子邮件模板发送群发电子邮件。 {!Receiving_User.field_name}和
{!Sending_User.field_name}合并字段仅适用于海量电子邮件和列表电子邮件,并且在Visualforce电子邮件模板中不可用。

以下示例显示如何定义显示与联系人关联的所有情况的Visualforce电子邮件模板。 该示例使用<apex:repeat>标签遍历与联系人有关的所有情况,并将它们合并到主体中
模板:

<messaging:emailTemplate recipientType=”Contact”
relatedToType=”Account”
subject=”Case report for Account: {!relatedTo.name}”
language=”{!recipient.Languages__c}”
replyTo=”support@acme.com”>
<messaging:htmlEmailBody>
<html>
<body>
<p>Dear {!recipient.name},</p>
<p>Below is a list of cases related to {!relatedTo.name}.</p>
<table border=”0″ >
<tr>
<th>Case Number</th><th>Origin</th>
<th>Creator Email</th><th>Status</th>
</tr>
<apex:repeat var=”cx” value=”{!relatedTo.Cases}”>
<tr>
<td><a href =
“https://yourInstance.salesforce.com/{!cx.id}”>{!cx.CaseNumber}
</a></td>
<td>{!cx.Origin}</td>
<td>{!cx.Contact.email}</td>
<td>{!cx.Status}</td>
</tr>
</apex:repeat>
</table>
<p/>
<center>
<apex:outputLink value=”http://www.salesforce.com”>
For more detailed information login to Salesforce.com
</apex:outputLink>
</center>
</body>
</html>
</messaging:htmlEmailBody>
</messaging:emailTemplate>

注意以下关于标记:

  • recipientType和relatedToType属性充当电子邮件模板的控制器。有了它们,您可以访问其他标准控制器可用的相同合并字段。 recipientType属性表示电子邮件的收件人。 relatedToType属性表示与电子邮件关联的记录。 
  • <messaging:htmlEmailBody>组件可以包含Visualforce标记和HTML的组合。 <messaging:plainTextEmailBody>组件只能包含Visualforce标记和纯文本。 
  • 要根据收件人或相关对象的语言翻译Visualforce电子邮件模板,请使用
    <messaging:emailTemplate>标签的语言属性(有效值:Salesforce支持的语言键,例如“en-US”)。 language属性接受来自电子邮件模板的recipientType和relatedToType属性的合并字段。您可以创建用于合并字段的自定义语言字段。翻译工作台需要翻译电子邮件模板。该示例使用合并字段为接收电子邮件的联系人获取语言属性。

Visualforce和闪电体验 – 了解闪电体验中应避免使用的功能

 

学习目标

完成本单元后,您将能够:

  • 列出至少两个组件以避免在Lightning Experience中使用的页面上使用。
  • 确定三个Lightning Experience功能,您无法使用Visualforce页面或组件。

了解在闪电体验中要避免哪些特征

我们建议您避免在Lightning Experience中使用的页面上存在有限数量的Visualforce组件。此外,在Lightning Experience中使用Visualforce的一些功能时会有不同的表现。最后,Lightning Experience中有几个地方不能使用Visualforce页面或应用程序,或者它们可能无法正常工作。
闪电体验还在不断发展和壮大,安全港警报! – 我们希望随着时间的推移缩小这个名单。

闪电体验标题和导航菜单不能被抑制

在Lightning Experience中运行时,Visualforce页面始终显示标准的Lightning Experience用户界面。没有办法抑制或改变Lightning Experience标题或边栏。特别是,在“Lightning Experience”中显示时,<apex:page>的showHeader和sidebar属性对Visualforce页面没有影响。
这种行为是有意的。在Lightning Experience中显示的应用程序是Lightning Experience应用程序。如果您需要为您的应用程序提供完全自定义的界面,则需要在Salesforce Classic中运行它。

Salesforce Classic标题和边栏始终被抑制

在Lightning Experience中显示时,标准Salesforce Classic标题和侧边栏始终会被隐藏。特别是,在“Lightning Experience”中显示时,<apex:page>的showHeader和sidebar属性对Visualforce页面没有影响。
页面的行为就好像<apex:page>的showHeader和sidebar属性都设置为false。

注意

确定是否包含或取消标准Salesforce Classic样式表的<apex:page>的standardStylesheets属性不受Lightning Experience的影响。也就是说,在Lightning Experience中它默认为true,但是你可以改变它。

<apex:relatedList>和黑名单相关列表

有许多相关的列表在Lightning Experience中不被支持。这些相关的名单是“黑名单”,这意味着他们被明确阻止使用。正如您所期望的那样,这些相同的相关列表在Visualforce中使用<apex:relatedList>标记列入黑名单。
有关Lightning Experience不支持哪些相关列表的详细信息,请参阅联机帮助中的“数据访问和视图:闪电体验中的不同或不可用”。

避免 <apex:iframe>

尽管在Lightning Experience的Visualforce页面上使用<apex:iframe>并非不可能,但我们建议避免使用它。
在Lightning Experience中显示时,Visualforce页面将封装在各自的iframe中。正如在探索Visualforce应用程序容器中详细讨论的那样,这对页面的行为有很多重要的影响。向iframe堆栈添加额外的级别会增加环境的复杂性。

如果您真的了解iframe以及它们如何影响DOM和JavaScript,则可以管理这种复杂性。但是除非你已经在使用嵌套的iframe,否则很难调试问题。出于这个原因,我们建议您避免在Lightning Experience中使用的页面上使用此标签。

不,真的,不要直接设置window.location

在这一点上,我们可能听起来像一个破碎的记录,但这很重要。如果你的页面的JavaScript代码直接设置了window.location变量,当页面显示在Lightning Experience中时,这个功能将不起作用。您必须修改此代码才能使页面在Lightning Experience中运行。
有关详情,请参阅管理导航单元。

sforce.one不是Salesforce Mobile-Only

sforce.one JavaScript实用程序对象可用于Salesforce应用程序和Lightning Experience中的Visualforce页面。如果您一直在使用sforce.one对象作为判断您的页面是否在移动或桌面环境中运行的方式,则需要更新代码。
使用其中一种记录的方法来区分Salesforce Classic,Salesforce应用程序和Lightning Experience环境。 Visualforce,Apex和JavaScript中提供了支持的技术。

有关完整的详细信息,请参阅在Classic和Lightning Experience之间共享Visualforce页面单元。

动作重写的更改

对于可能难以解决的事情,Visualforce覆盖标准操作的最显着的变化可能与Lightning Experience相比略有不同。 Lightning Experience中将无法访问对象列表操作的任何覆盖。
具体而言,您可以在Salesforce Classic中为对象覆盖六个标准操作:
  • Object tab
  • Object list
  • Record view
  • Record edit
  • Record create
  • Record delete

在闪电体验中,前两个动作合并为一个页面,将对象归入主页。对象首页与对象列表类似,添加了对象选项卡的一些元素,例如最近的项目。其他的,如报告或工具,已经转移到用户界面的其他部分。
无论组织中的用户界面设置如何,“对象”选项卡和对象列表都可在“设置”中被覆盖。按照预期,覆盖对象选项卡操作将覆盖Lightning Experience中的对象主页。

但是,在Lightning Experience中,对象列表操作在用户界面中无法访问,因此无法将其解除。如果您的组织已经重写了任何对象的对象列表操作,那么当用户使用Lightning Experience时,该功能将不可用。如果在重写中有必要的功能,则需要找到其他方法使其可用。

此表列出了您可以在安装程序中替代对象的标准操作,以及三种不同用户体验中覆盖的操作。

在设置中覆盖 Salesforce Classic 闪电的经验 Salesforce应用程序
选项卡 对象选项卡 对象主页 搜索
列表 对象列表 n/a 对象主页
视图 记录视图 记录主页 记录主页
编辑 记录编辑 记录编辑 记录编辑
创建 纪录创建 纪录创建 纪录创建
删除 记录删除 记录删除 记录删除

注意

“n/a”并不意味着您不能访问标准行为,也并不意味着您不能覆盖标准行为。 这意味着你不能访问覆盖。 这是覆盖的功能,不可用。

Visualforce和闪电体验 – 了解重要的视觉设计注意事项

学习目标

完成本单元后,您将能够:

  • 描述改变内置Visualforce组件样式的两种方法。
  • 描述可以使用CSS样式表进行更改的Salesforce Classic和Lightning Experience样式之间的差异。
  • 描述将Salesforce Lightning设计系统应用于Visualforce页面的两种方法。

了解重要的视觉设计注意事项

无论是在Salesforce Classic还是Lightning Experience中运行,Visualforce页面都是一样的,除非您重新修改它们以适应适当的用户界面上下文。显示用户界面元素的内置Visualforce组件不容易重新配置,以与Lightning Experience外观相匹配。
具体而言,当页面显示在Lightning Experience中时,由内置的Visualforce组件呈现的HTML不会更改,并且这些组件使用的Salesforce Classic样式表默认情况下由页面加载。其效果是,使用<apex:inputField>,<apex:outputField>,<apex:pageBlock>组件以及与Salesforce Classic可视化设计相匹配的其他粗糙和精细组件的页面仍然与该可视化设计相匹配。您在Lightning Experience中获得一小部分Salesforce Classic。

这是我们的一般建议,现在,对于现有的网页,你不要试图去适应闪电体验的视觉设计。闪电体验仍在不断发展,自己的造型搭配意味着你正在追逐一个移动的目标。这是工作。

不过,在某些情况下,您会希望某些页面与Lightning Experience的视觉效果更加匹配。对于新的页面,或者如果你愿意做一些工作,有一些很棒的工具可以用来创建完全符合Lightning Experience的页面。

影响标准件的样式

Visualforce为调整或覆盖标准组件的样式提供了一系列选项。如果您的目标是对这些组件的外观进行适度的更改,则使用这些选项的努力也是同样适度的。我们来看看可用于影响样式的一些工具。

个别组件样式

生成HTML的Visualforce组件具有传递样式和styleClass属性。这些属性允许您使用自己的样式和样式类来控制生成的HTML的外观和风格。样式允许您直接在组件上设置样式,而styleClass则允许您为别处定义的样式附加类。例如,以下代码设置<apex:outputText>的类并应用样式。

<apex:page>

    <style type="text/css">
        .asideText { font-style: italic; }
    </style>

    <apex:outputText style="font-weight: bold;" 
        value="This text is styled directly."/>

    <apex:outputText styleClass="asideText" 
        value="This text is styled via a stylesheet class."/>

</apex:page>

添加一个自定义样式表

您可以使用静态资源和<apex:stylesheet>标记将自己的自定义样式表添加到任何Visualforce页面。例如,要添加一个样式表作为名为“AppStylesheet”的静态资源上传,请在页面中添加以下内容。

<apex:stylesheet value="{!$Resource.AppStylesheet}"/>

然后,您可以引用样式表中包含的任何样式,并在Visualforce标记styleClass属性中引用它们,就像我们之前使用asideText样式所做的那样。
这是将CSS样式定义添加到Visualforce页面的推荐方法,因为它共享页面之间的样式表,并最小化您需要添加到每个页面的标记。

Salesforce Lightning设计系统是用于添加样式表的这种方法的例外。闪电设计系统是一个梦幻般的全新的网页造型工具,我们将在不久后详细讨论。

尽管您可以将Lightning设计系统作为静态资源上传,并使用<apex:stylesheet>进行引用,但还有一种更简单的方法:只需在页面标记中的任意位置包含<apex:slds />即可。

闪电体验中的不同风格

仅当您的页面在Lightning Experience中运行时才加载自定义样式表,请使用以下标记。这与在经典和闪电体验之间共享Visualforce页面中的Visualforce标记示例类似。

<apex:page standardController="Account">

    <!-- 基础样式 -->
    <apex:stylesheet value="{!URLFOR($Resource.AppStyles, 'app-styles.css')}" />
    
    <!-- 闪电桌面额外的样式 -->
    <apex:variable var="uiTheme" value="lightningDesktop" 
        rendered="{!$User.UIThemeDisplayed == 'Theme4d'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles, 'lightning-styling.css')}" />
    </apex:variable>

    <!-- 其余的页面 -->
    
</apex:page>
好的,这些都是工具。让我们看看接下来使用它们的一些技巧。

样式的策略和建议

要创建与Lightning Experience可视化设计相匹配的Visualforce页面,请使用Lightning Design System创建新页面。在Visualforce页面中使用Lightning Design System有两种方法。
在详细讨论之前,我们先考虑一下更高的层次,并考虑将闪电体验风格应用于网页的不同策略。具体来说,我们来谈谈你现有的页面。

有两种方法可以影响现有页面的样式,使其看起来更像闪电体验。

  • 更改标记以在页面中应用新的样式更改。
  • 更改样式表中现有标记更改的样式规则。

这些都不是/或。您可以单独使用或组合使用它们。

正确使用Lightning Design System意味着使用Lightning Design System样式表和全新的标记来显示Visualforce页面。同样,这是匹配Lightning Experience可视化设计的唯一支持的方法。

要做到这一点,您可以从他们的网站下载Lightning Design System样式表,并像使用其他样式表一样使用它们,也可以将<apex:slds>组件添加到Visualforce页面的标记中。 <apex:slds>组件允许您引用Lightning Design System样式表,而无需将其上载为静态资源,从而简化了页面的语法并防止您达到250 MB的静态资源限制。

使用<apex:slds>带有自己的一套准则和注意事项。如果您想了解更多信息,请参阅Lightning Design System徽章或查看参考资料部分的Visualforce Developer Guide链接。

也可以添加Lightning Design System样式表,并修改您的页面以使用它们。这是多少工作取决于你想如何紧密匹配Lightning Experience以及代码中的特定标记和组件。虽然以这种方式取得体面的结果是可能的,但是,这不是我们推荐的方法。闪电设计系统被设计用于特定的标记,这根本不是Visualforce发出的。有一个“阻抗不匹配”,虽然不是致命的,但当你走这条路时,肯定是你的鞋子里的一块严重的石头。

最后,还有另外一种方法:为现有的(或新的)样式表添加新的规则和样式,使现有的标记看起来更像Lightning Experience。如果您的页面已经大部分使用自己的样式表,那么这种方法可能适合您。相反,如果您主要使用内置的Visualforce组件和Salesforce Classic样式,则需要覆盖Salesforce Classic样式表中的样式。

尽管这在技术上是可行的,但我们希望阻止您采取这种方法。它将依赖关系引入到您不想拥有的标记和样式中。这些依赖关系位于由内置的Visualforce组件呈现的HTML的结构,ID和类中。我们希望在这里真正清楚:由内置的Visualforce组件呈现的HTML是内部实现细节,如有更改,恕不另行通知。如果您在自己的样式表中有依赖关系,那么您的样式将最终中断。

Salesforce闪电设计系统

闪电设计系统是用于构建类似闪电体验的企业应用程序的设计框架。它包含一个复杂的CSS框架,一组图形资产和Salesforce Sans字体。您可以使用闪电设计系统构建看起来非常华丽的页面和应用程序,并与Lightning Experience用户界面完美匹配。
闪电设计系统旨在使客户和合作伙伴轻松匹配闪电体验的外观和感觉。它还包括可以自定义外观和风格以匹配自己品牌颜色等的工具,同时仍然与整体Lightning Experience设计保持一致。

闪电设计系统如此之大,如此令人兴奋……我们不打算详细介绍在这里使用闪电设计系统。因为我们已经写了一个关于使用它的整个模块,Lightning Design System。它解释了如何获得Lightning Design System,使用它来设计页面的基本概念,以及如何将这些概念应用于使用Visualforce构建Lightning Experience应用程序。

闪电设计系统是一个很大的模块,你必须努力获得这个徽章。虽然我们希望保存这个模块的细节,但是我们不想让你完全挂在这里。那么,让我们介绍一下如何在Visualforce中使用Lightning Design System。

首先要知道的是,闪电设计系统采用了新的标记结构和样式类。出于这个原因,最好使用新的页面和应用程序。它建立在现代浏览器功能的基础上,并利用最新的标记和样式最佳实践。尽管我们都喜欢它,Visualforce已经有一段时间了。在它生成的HTML和客户页面中的静态代码之间,大多数组织将发现将Lightning设计系统应用于现有页面具有挑战性。

闪电设计系统模块专注于创建新的页面和应用程序,并且对该徽章进行评分是了解它的最佳方式。完成该模块后,您将了解如何使用Lightning设计系统,以及如何计划周围的开发。

Visualforce和闪电体验 – 管理导航

学习目标

完成本单元后,您将能够:

  • 描述用于控制从一个页面到另一个页面的三种“经典”Visualforce机制。
  • 描述哪些技术在Lightning Experience中不起作用。
  • 列出至少三个闪电体验导航事件,以及如何发送。

管理导航

应用程序流和导航在许多方面是应用程序设计的核心。 Visualforce提供了多种添加导航元素和指导应用程序流的方法。 Lightning Experience添加了自己的应用程序流程,导航元素和机制,以影响用户在使用Salesforce时的位置。
好消息是,“经典”的Visualforce导航继续工作。更好的消息是您的Visualforce页面也可以利用新的Lightning Experience机制。

导航闪电的经验

在我们谈论Visualforce导航的细节之前,以及如何创建它以使其在Salesforce Classic和Lightning Experience中起作用之前,我们先谈谈导航。 “导航”我们究竟意味着什么?
我们可能通过导航的第一件事是屏幕上的用户界面元素。你点击一下,发生什么事情。例如,您可以单击导航菜单中的“帐户”项目,然后转到“帐户”对象主页。您单击新建按钮,并出现记录条目窗体。您从快速操作菜单中选择自定义操作,然后启动自定义过程。等等。这些按钮和菜单项是导航元素。

导航系统(Lightning Experience中的用户界面)的设计与Salesforce Classic有很大不同。我们不打算在这里谈论这些差异,但是当您在两种用户体验之间切换时,您会希望熟悉所有事情的动向。您可以在Trailhead的导航闪电体验和设置单元中了解更多关于此的信息。

另一种较不明显的导航类型是上述“发生了什么”部分。在幕后,Salesforce决定在菜单中选择某个项目时发生的情况,或者单击链接或按钮。大部分导航已经内置到Salesforce中,而其他方面则是可定制的 – 例如,使用Visualforce页面覆盖操作。但是,所有这些导航都是由Salesforce编写的代码管理的。

然后在自己的应用程序中导航 – 使用您的代码来控制应用程序流的应用程序。当你的自定义操作打开一个表单,用户点击保存,你去哪里?当你的运行代码决定下一个用户应该去哪里,并在那里发送它们。这就是我们要在这个单元里讨论的内容。

经典的Visualforce导航
“经典”Visualforce导航可以归结为“在操作方法结束时会发生什么”。操作方法返回PageReference对象,其中包含用户要导航到的位置的详细信息,然后Visualforce框架将处理将正确的响应发送回用户的浏览器。而且,好消息,这一切仍然有效。
还要记住标准控制器从其操作方法中返回一个PageReference。因此,无论您使用的是标准控制器还是您自己的自定义控制器代码,您的现有导航都可以按照您的预期继续工作。

经典Visualforce导航

“经典”Visualforce导航可以归结为“在操作方法结束时会发生什么”。操作方法返回PageReference对象,其中包含用户要导航到的位置的详细信息,然后Visualforce框架将处理将正确的响应发送回用户的浏览器。而且,好消息,这一切仍然有效。
还要记住标准控制器从其操作方法中返回一个PageReference。因此,无论您使用的是标准控制器还是您自己的自定义控制器代码,您的现有导航都可以按照您的预期继续工作。

现代Visualforce导航

所以,如果经典的Visualforce导航工作,为什么我们仍然在谈论这个?我们甚至在谈论什么?我们只想对你说一个字。只是一个字。你在听么? …“JavaScript”。
JavaScript有一个很好的未来,而今天就在这里。许多Visualforce开发人员在他们的应用程序中大量使用JavaScript,并且这种使用持续增长。经典的Visualforce工作,并将继续工作很长一段时间。但是,随着开发人员采用远程对象和JavaScript远程等Visualforce功能,他们更多的应用程序的行为从服务器端迁移到浏览器和JavaScript,在那里没有PageReference这样的事情。

在Lightning Experience(和Salesforce应用程序)世界中,有一些用于在JavaScript中构建导航的规则和工具。我们将会介绍一些规则,主要是关于不该做的事情。先谈谈正确的做事方式吧。

Lightning Experience使用事件管理导航。导航事件框架作为一个JavaScript实用程序对象提供,该对象提供了许多可以直接创建程序化导航的功能。在运行Lightning Experience时,sforce.one对象会自动添加到Visualforce页面。这个对象提供了一些函数调用函数时触发导航事件。要使用这些功能,您可以直接从页面的JavaScript代码中调用它们,也可以将调用作为单击(或其他)处理程序附加到页面上的元素。

重要

sforce.one对象在Salesforce Classic中不可用。任何使用它的代码都应该首先测试sforce.one的存在。

sforce.one对象提供以下功能。引用来自sforce.one对象的使用虚线符号的函数。例如:sforce.one.navigateToSObject(…)。

功能 描述
back(​[refresh]) 导航到sforce.one历史中保存的以前的状态。这相当于单击浏览器的“后退”按钮。
navigateToSObject(​recordId​[, view]) 导航到由recordId指定的sObject记录。
navigateToURL(​url​[, isredirect]) 浏览到指定的网址。
navigateToFeed(​subjectIdtype) 导航到指定类型的供稿,其范围为subjectId。
navigateToFeedItemDetail(​feedItemId) 导航到特定的feed项目,feedItemId和任何关联的注释。
navigateToRelatedList(​relatedListIdparentRecordId) 导航到parentRecordId的相关列表。
navigateToList(​listViewId​, listViewNamescope) 导航到listViewId指定的列表视图,listViewId是要显示的列表视图的ID。
createRecord(​entityName​[, recordTypeId]) 打开页面为指定的entityName创建新记录,例如“Account”或 “MyObject__c”。
editRecord(​recordId) 打开页面以编辑由recordId指定的记录。

有关使用这些函数的更多详细信息及其接受的参数,请参阅本机资源中的使用sforce.one对象的导航。

导航问题,以及如何解决这些问题

在JavaScript中构建Visualforce导航的第一条规则是:不要直接设置window.location。在JavaScript中构建Visualforce导航的第二个规则是:不要直接设置window.location。

不要直接设置window.location

好的,无偿的重复和电影的参考,这里有什么大不了的?这很简单。当在闪电体验您的网页没有window.location设置!还记得之前关于Visualforce“容器”的讨论,还有一个关于iframe的内容,Lightning Experience是某种健康俱乐部? (SPA单页申请。)这是其中的一个东西。 Visualforce iframe不能直接访问window.location的值,所以你不能设置它。如果你的代码依赖于设置,它会中断。也就是说,通过设置window.location来触发导航的动作将停止导航到您期望的任何位置。

实际上有一个解决这个限制的方法,但是你不应该使用它。原因是,如果绕过sforce.one中的导航功能,您的导航事件将不会在Lightning Experience导航堆栈中进行跟踪。该堆栈提供了有用的功能,例如说明重定向等的后退按钮。 Lightning Experience(特别是Salesforce应用程序)中的许多功能都依赖于包含所有导航事件的堆栈。确保您正确使用它是值得的。

Salesforce Classic问题

所以,是的,这是一个…的东西。不幸的是,当您的页面在Salesforce Classic中运行时,sforce.one实用程序对象不可用。在这种情况下,你必须使用window.location。好消息是,在Salesforce Classic中,window.location可用。坏消息是,这个限制意味着你将不得不添加一个丑陋的if块给你的代码。考虑将导航功能包装在处理这种复杂性的实用程序方法中,以便您的主要导航逻辑可以很简单。

静态网址

不要将静态URL用于Salesforce资源。也就是说,如果要添加一个链接来编辑联系人记录,请不要使用link =’/’+ accountId +’/ e’等静态模式创建链接。在某些情况下,这是有效的,但在其他情况下则不行。相反,尝试以下方法之一:

  • 在Visualforce标记中,使用 {!URLFOR($Action.Contact.Edit, recordId)}
  • 在JavaScript中,使用 navigateToSObject(recordId)

有查看,创建,编辑等操作和功能。使用它们,而不是URL字符串。

Visualforce和闪电体验 – 在经典体验和闪电体验之间共享Visualforce页面

学习目标

完成本单元后,您将能够:

  • 列出Salesforce Classic和Lightning Experience共享页面的两个好处。
  • 描述用户所请求的用户界面上下文与用户实际所在的用户界面上下文之间的区别。
  • 描述测试和确定当前用户的用户界面上下文的三种不同方式。

在经典和闪电体验之间共享Visualforce页面

我们建议尽可能创建Visualforce页面,无论这些页面是在Salesforce Classic还是Lightning Experience中运行。降低组织代码和配置复杂性的好处是显而易见的。还有一些上下文,例如Visualforce替代标准操作,你没有选择的地方。无论您是在Salesforce Classic,Lightning Experience还是Salesforce应用程序中运行,操作覆盖总是使用相同的页面。
然而,这是完全合理的,希望基于用户体验上下文在其中运行的行为或样式稍微或明显不同。在本单元中,我们将介绍各种创建可在所有用户体验中正常工作的页面的方法,以及代码如何检测特定上下文并对其进行更改。

在Visualforce标记中检测和响应用户体验上下文

使用$ User.UITheme和$ User.UIThemeDisplayed全局变量来确定当前的用户体验上下文。您可以在Visualforce表达式中使用这些变量,使页面适应Lightning Experience,Salesforce Classic和Salesforce应用程序。
这些全局变量返回一个唯一标识当前用户界面上下文的字符串。 $ User.UITheme和$ User.UIThemeDisplayed的可能值是相同的:
  • Theme1 – 已过时的Salesforce主题
  • Theme2-Salesforce Classic 2005用户界面主题
  • Theme3-Salesforce Classic 2010用户界面主题
  • Theme4d – 现代“闪电体验”Salesforce主题
  • Theme4t-Salesforce移动应用程序Salesforce主题
  • PortalDefault-Salesforce客户门户主题
  • Webstore-Salesforce AppExchange主题

两个变量的区别在于$ User.UITheme返回用户应该看到的外观,而$ User.UIThemeDisplayed返回用户实际看到的外观。例如,用户可能有首选项和权限来查看Lightning Experience外观,但是如果他们使用的浏览器不支持该外观(例如,旧版本的Internet Explorer),则$ User.UIThemeDisplayed返回一个不同的值。一般来说,你的代码应该使用$ User.UIThemeDisplayed。
使用这些主题全局变量的最简单的方法是在布尔表达式中使用一个,如{! $ User.UIThemeDisplayed ==“Theme3”},在组件的呈现属性。只有页面出现在所需的用户界面上下文中时,组件才会显示。

<apex:outputText value="This is Salesforce Classic." 
    rendered="{! $User.UIThemeDisplayed == 'Theme3' }"/>
虽然您可以在单独的用户界面元素上使用此技术,但是如果将较大的标记块包装到<apex:outputPanel>或类似的块级别组件中,则通常会更有效,然后为每个想要呈现的不同UI创建单独的块。然后将主题测试放置在块的呈现属性上,而不是单个组件。这不仅应该表现得更好,你的代码将不那么复杂。
<apex:outputPanel rendered="{! $User.UIThemeDisplayed == 'Theme3' }">
    <apex:outputText value="This is Salesforce Classic."/>
    <apex:outputText value="These are multiple components wrapped by an outputPanel."/>
</apex:outputPanel>
<apex:outputPanel rendered="{! $User.UIThemeDisplayed == 'Theme4d' }">
    <apex:outputText value="Everything is simpler in Lightning Experience."/>
</apex:outputPanel>
您可以使用的另一个策略是动态选择要包含在页面上的样式表,并为每个主题提供不同的样式表。这比您想象的要复杂一些,因为<apex:stylesheet>标记没有自己的渲染属性。在这种情况下,您必须将样式表组件包装在具有渲染属性的另一个组件中。以下是如何为Salesforce支持的三个现代主题中的每一个提供不同样式表的示例。
<apex:page standardController="Account">

    <!-- Salesforce Classic "Aloha" theme -->
    <apex:variable var="uiTheme" value="classic2010Theme" 
        rendered="{!$User.UIThemeDisplayed == 'Theme3'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles, 
                                         'classic-styling.css')}" />
    </apex:variable>
    
    <!-- Lightning Desktop theme -->
    <apex:variable var="uiTheme" value="lightningDesktop" 
        rendered="{!$User.UIThemeDisplayed == 'Theme4d'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles, 
                                         'lightning-styling.css')}" />
    </apex:variable>
    
    <!-- Salesforce mobile theme -->
    <apex:variable var="uiTheme" value="Salesforce1" 
        rendered="{!$User.UIThemeDisplayed == 'Theme4t'}">
        <apex:stylesheet value="{!URLFOR($Resource.AppStyles, 
                                         'mobile-styling.css')}" />
    </apex:variable>

    <!-- Rest of your page -->
    
    <p>
        Value of $User.UIThemeDisplayed: {! $User.UIThemeDisplayed }
    </p>
</apex:page>

超越基础

这是使用<apex:variable>的一种不寻常的方法,因为我们实际上并不关心创建的变量的值。相反,我们只需要一个组件,它不会自己提供任何输出来包装<apex:stylesheet>组件。您可以将其视为<apex:variable>“借出”其呈现的属性到包装的<apex:stylesheet>组件。

我们并不关心变量本身,这是一件好事,因为另外一个不寻常的方面就是变量不是真正创建的!功能或错误?我们称之为…未定义的行为,并避免在其他地方使用uiTheme变量。

在JavaScript中检测和响应用户体验上下文

在JavaScript代码中检测当前用户体验上下文非常重要,如果您在页面和应用程序中使用JavaScript。使用正确的技术来管理JavaScript代码中的导航特别重要。在您的JavaScript代码中处理UX上下文检测的最佳方法是使用可在任何地方使用的实用函数库。
起初,这看起来很简单,只需测试Visualforce标记中提供的相同全局变量即可。也许这样的事情
function isLightningDesktop() {
    return( "{! $User.UIThemeDisplayed }" == "Theme4d");
}

如果您将此代码添加到Visualforce页面,则它可以工作。
这是问题。只要将此代码移动到静态资源中(这是代码组织的最佳实践,提高性能和其他原因),它就会停止工作,因为全局变量在静态资源中不可用。不会为标记或表达式或全局处理静态资源,或者根本不处理静态资源。他们只是服务。这就是为什么我们称之为静态资源。 😉

那么,我们如何做到这一点,而不是在每个需要测试用户体验上下文的页面中添加重复的JavaScript代码呢?通过创建一个非常简单的页面,只需将$ User.UIThemeDisplayed值插入到正确的JavaScript上下文中,然后使用<apex:include>将其添加到页面。然后我们可以在我们的实际工具代码中测试注入的值。

下面是我们用于将$ User.UIThemeDisplayed全局变量注入到JavaScript上下文中的“shim”Visualforce页面,以及包含使用它的JavaScript实用程序静态资源。

<apex:page docType="html-5.0" applyBodyTag="false" applyHtmlTag="false"
           showHeader="false" standardStylesheets="false">

<!-- UIUTILS SCRIPT -->
<apex:includeScript value="{!URLFOR($Resource.ForceUI)}"/>
<!-- UIUTILS SCRIPT -->

<!-- UITHEME INJECTOR -->
<script type="text/javascript">
    (function(myContext){
        // 如果我们已经存在,不要覆盖自己。
        myContext.ForceUI = myContext.ForceUI || {};
        
        // 因为这是Visualforce,不是一个静态资源,
        // 我们可以在表达式中访问一个全局变量。
        myContext.ForceUI.UserUITheme = '{! $User.UIThemeDisplayed }';
    })(this);
</script>
<!-- UITHEME INJECTOR -->

</apex:page>

这个页面有两件事。首先,它抽取包含实际工具方法代码的JavaScript静态资源。 (其中,我承诺,我们将继续讨论)。其次,它有一个内联JavaScript,因为它在Visualforce页面中运行,而不是静态资源,因此可以使用全局主题评估表达式。此脚本在ForceUI实用程序对象内设置一个变量。这会将Visualforce的主题值复制到JavaScript中,以便可以通过静态资源中的JavaScript代码进行引用。

这个“页面”不是直接访问,而是包含在你的真实页面中。这使得在这些页面中添加JavaScript实用程序方法成为单行的工作。 (如果你记得#include不是你在社交媒体上做的事情,那么举起你的手,就在那儿,现在让我们把那些孩子从那个草坪上拿走吧!)

我们来看看如何使用它。这是一个非常简单的页面,展示了如何使用<head>块中的<apex:include>组件将JavaScript实用程序方法添加到页面中。在页面底部是一小段JavaScript,演示了如何使用JavaScript中的实用工具方法。我们在代码中加入了重点来突出这些元素。

<apex:page standardController="Account" extensions="ForceUIExtension"
           showHeader="false" standardStylesheets="false"
           applyHtmlTag="false" applyBodyTag="false"
           docType="html-5.0" title="ForceUI Utilities">

<html lang="en">
  <head>
    <title>ForceUI Utilities</title>
    <apex:include pageName="UIThemeUtilsInclude"/>
  </head>

  <body>
      
    <h1>ForceUI Utilities</h1>
    
    <p>This is a page used for testing different ways of determining 
       the user interface context in which it's being displayed.</p>
    
    <h2>$User.UITheme Global Variable</h2>
    
    <p><label>$User.UITheme</label>: {! $User.UITheme }</p>
    <p><label>$User.UIThemeDisplayed</label>: {! $User.UIThemeDisplayed }</p>
    
    
    <h2>UIUtils JavaScript</h2>
    
    <p><label>ForceUI.UserUITheme</label>: 
       <span id="UserUIThemeJS">(loading...)</span></p>
      
    <p><label>isSalesforce1()</label>: 
       <span id="isSalesforce1JS">(loading...)</span></p>
      
    <p><label>isLightningExperience()</label>: 
       <span id="isLightningExperienceJS">(loading...)</span></p>
      
    <p><label>isSalesforceClassic()</label>: 
       <span id="isSalesforceClassicJS">(loading...)</span></p>

    <script type="text/javascript">
      document.addEventListener('DOMContentLoaded', function(event){
          // 仅诊断 - 不要直接使用此值
          document.getElementById('UserUIThemeJS').innerHTML = ForceUI.UserUITheme;
          // 而是使用这些实用方法
          document.getElementById('isSalesforce1JS').innerHTML = 
              ForceUI.isSalesforce1();
          document.getElementById('isLightningExperienceJS').innerHTML = 
              ForceUI.isLightningExperience();
          document.getElementById('isSalesforceClassicJS').innerHTML = 
              ForceUI.isSalesforceClassic();
      });
    </script>
  </body>
</html>
</apex:page>
在您的组织,Lightning Experience,Salesforce Classic甚至Salesforce应用程序中查看此页面,以确认这些值取决于环境而变化。
最后(#finally),这里是包含JavaScript实用程序函数的实用程序库,它允许您创建表达式,以根据运行的用户界面上下文有条件地影响应用程序JavaScript代码的结果。
// 这是一个匿名的自动执行的函数关闭thingie,
// 像所有这些天凉爽的孩子一样
(function(myContext){

    // 处理可能的执行顺序问题。
    // 如果我们已经存在,不要覆盖自己。
    myContext.ForceUI = myContext.ForceUI || {};

    // 根据本地UserUITheme值进行简单字符串比较的实用程序方法。
    // 该值从Visualforce页面注入,
    // 以允许$ User.UIThemeDisplayed全局的表达式评估。
    myContext.ForceUI.isSalesforceClassic = function() {
        return (this.UserUITheme == 'Theme3');
    }
    myContext.ForceUI.isLightningExperience = function() {
        return (this.UserUITheme == 'Theme4d');
    }
    myContext.ForceUI.isSalesforce1 = function() {
        return (this.UserUITheme == 'Theme4t');
    }
})(this);

除了自执行函数可能不熟悉的语法之外,这里的代码是非常简单的。代码执行的结果是一个实用程序对象ForceUI,添加到您的页面的全局范围。该对象从早期的Visualforce填充页面中的JavaScript注入器接收$ User.UIThemeDisplayed全局变量的值。该值保存在一个名为UserUITheme的本地变量中,您应该将其视为一个私有的实现细节。切勿直接访问它!

该对象的公共API被暴露为一系列的函数,isLightningExperience()等等,你在代码的其余部分中使用,如上图所示。您甚至可以添加自己的附加功能,例如,从桌面或从简单的Visualforce中分配one.app。

确定Apex中的用户体验环境

使用UserInfo.getUiTheme()和UserInfo.getUiThemeDisplayed()系统方法确定Apex代码中的当前用户体验上下文。当你的控制器动作方法或属性需要在不同的上下文中表现不同时,你可以使用它们。
以下示例说明了如何通过在控制器扩展中通过getter方法使用这些方法来使用这些方法。
public with sharing class ForceUIExtension {

    // Empty constructor, required for Visualforce controller extension
    public ForceUIExtension(ApexPages.StandardController controller) { }
    
    // Simple accessors for the System.UserInfo theme methods
    public String getContextUserUiTheme() {
        return UserInfo.getUiTheme();
    }    
    public String getContextUserUiThemeDisplayed() {
        return UserInfo.getUiThemeDisplayed();
    }    

}
您当然可以使用Apex代码中的值,而不是直接返回方法调用结果。
这些Apex系统方法返回一个唯一标识当前用户界面上下文的字符串。这些方法返回的可能值与$ User.UITheme和$ User.UIThemeDisplayed全局变量返回的值相同。
Theme1 – 已过时的Salesforce主题
  • Theme1 – 已过时的Salesforce主题
  • Theme2-Salesforce Classic 2005用户界面主题
  • Theme3-Salesforce Classic 2010用户界面主题
  • Theme4d – 现代“闪电体验”Salesforce主题
  • Theme4t-Salesforce移动应用程序Salesforce主题
  • PortalDefault-Salesforce客户门户主题
  • Webstore-Salesforce AppExchange主题

在服务器端控制器代码中使用这些方法应该很少,至少与提供不同的Visualforce标记或JavaScript代码相比。对于您的控制器和控制器扩展代码来说,在UX上下文中是最好的做法。让您的前端代码(无论是Visualforce还是JavaScript)处理用户界面差异。

通过SOQL和API访问查询闪电体验

虽然我们不推荐这种技术,但您可以直接使用SOQL查询当前用户的首选用户体验。
基本的SOQL查询如下。
SELECT UserPreferencesLightningExperiencePreferred FROM User WHERE Id = 'CurrentUserId'
结果是一个原始的偏好值,你需要转换成可用的东西。
以下是运行上述SOQL查询的最简单的Visualforce页面,并在页面上显示结果。
<apex:page>

<script src="/soap/ajax/36.0/connection.js" type="text/javascript"></script>
<script type="text/javascript">

    // 查询偏好值
    sforce.connection.sessionId = '{! $Api.Session_ID }';
    var uiPrefQuery = "SELECT Id, UserPreferencesLightningExperiencePreferred " +
                      "FROM User WHERE Id = '{! $User.Id }'";
    var userThemePreferenceResult = sforce.connection.query(uiPrefQuery);
    
    // 在页面上显示返回的结果
    document.addEventListener('DOMContentLoaded', function(event){
        document.getElementById('userThemePreferenceResult').innerHTML = 
            userThemePreferenceResult;
    });
</script>

<h1>userThemePreferenceResult (JSON)</h1>

<pre><span id="userThemePreferenceResult"/></pre>

</apex:page>
不鼓励直接查询用户的Lightning Experience偏好。结果将告诉您用户当前的首选项设置是什么,而不是用户的实际体验。有几种使用情况下,首选项值可能不会反映实际交付的用户体验。要确定当前请求中传递的实际用户体验,请使用$ User.UIThemeDisplayed或UserInfo.getUiThemeDisplayed()。

Visualforce和闪电体验 – 探索Visualforce应用容器

学习目标

完成本单元后,您将能够:

  • 描述在Salesforce Classic中运行的Visualforce页面与在Lightning Experience中运行的相同页面之间的三个区别。
  • 描述需要更新才能在Lightning Experience中工作的两种常见代码模式。
  • 在Lightning Experience中运行时,列出对Visualforce页面默认值的两个更改。

探索Visualforce应用程序容器

Lightning Experience中的Visualforce与Salesforce Classic中的Visualforce最大的区别在于它运行的环境。在Salesforce Classic中,Visualforce“拥有”页面,请求和环境。 Visualforce是应用程序容器。但是在Lightning Experience中,Visualforce在包含在较大的Lightning Experience容器内的iframe中运行。
这种对执行上下文的更改对Visualforce页面可能影响整个Salesforce应用程序的方式有很多影响。我们将在这个单元中讨论这些变化,但是为他们自己的单位保存其中一些的全部细节。

注意

这个单位比其他的“在建”还要多一点。原因很简单:这里描述的问题的影响高度依赖于你的代码。我们非常努力地为你们“做好工作”,而且在大多数情况下,这里一点或者什么都不会显示出来。但我们无法预测您使用Visualforce的各种方式。这里我们概述Lightning Experience如何影响Visualforce的一般方面。当你和我们交谈时,当我们从你那里得到更多关于实际影响的信息时,我们可以提供关于如何解决具体问题的更多细节的解释。

外部闪电体验容器

我们从外部容器Lightning Experience应用程序开始。 Lightning Experience容器是一个“单页面应用程序”或SPA,可以在/one/one.app URL访问。 one.app页面加载,代码启动,应用程序代码接管环境。
单页面应用程序加载资源的过程(通常是静态的HTML shell和大量的JavaScript)既有趣又复杂。如果你已经使用了AngularJS或者React之类的JavaScript框架,那么你就非常熟悉以one.app的形式启动Lightning Experience的基础知识。说实话,完整的细节并不重要。你没有任何控制权,并且实现继续发展。

以下是重要的知识:Lightning Experience或one.app负责请求。您的Visualforce页面不是。您的页面需要在Lightning Experience强加给它的限制内工作。 Lightning Experience是父级环境,而Visualforce页面是子级环境。孩子需要服从父母。

其中一些约束条件(例如显示Visualforce页面的框架的大小)直接由Lightning Experience强制实施。他们更容易理解和使用,我们将在一分钟内讨论他们。

其他限制是隐含的,并不是由Lightning Experience实施,而是由运行它的浏览器实施。这些主要是安全性和JavaScript执行的限制。大多数页面不受这些安全约束的影响,而且那些通常会提前失败并带有明确的错误消息。 JavaScript错误很难发现和诊断,但是有一些通用的规则,我们稍后会介绍。

Visualforce iframe

当您的Visualforce页面在Lightning Experience中运行时,它将显示在HTML iframe中。一个iframe创建一个嵌入式浏览上下文,这个浏览上下文实际上是一个独立于主Lightning Experience浏览上下文的浏览器“窗口”。 iframe在Visualforce页面与其父项Lightning Experience应用程序之间创建一个边界。
在iframe中运行Visualforce页面的优点是,对于不需要访问或更改顶级浏览上下文的页面,在iframe中运行看起来几乎与Salesforce Classic中的页面一样运行。这就是为什么您不需要修改所有Visualforce页面以适应Lightning Experience的大量不同的幕后请求环境。这是支持Visualforce的“正常工作”策略的重要组成部分。

当然,另一方面是那些需要访问顶层浏览上下文的页面,还有一些需要改变的地方。我们将在下一节介绍一些细节。

如果您的页面与Salesforce之外的服务进行通信,则iframe边界也可能导致您需要更新组织的CORS设置,远程站点设置,clickjack设置或内容安全策略。由于这些依赖于Salesforce之外的安全策略和设置,因此我们无法提供特定更改的配方。我们在这里简单地提醒你注意。

新容器的影响

新的Visualforce容器 – 将Lightforce页面嵌入到Lightning Experience应用程序的iframe中 – 可以大致分为两类,我们将其称为安全性和范围。
再一次,我们要强调的是:很多,甚至是大多数Visualforce页面都不会受到这些问题的影响。但是对于那些,我们认为“预先警告已经被警告”。如果我们已经一起讨论过,你会更快地发现问题的根源。

安全影响

可能受到影响的安全要素包括以下内容。

  • 会话维护和更新
  • 认证
  • 跨域请求
  • 嵌入限制

我们已经简要地讨论了一些这些涉及跨域请求的项目。也就是说,当完整的浏览器窗口中的内容来自对不同服务器和服务的请求时,这些请求中的任何一个都可能会妨碍在没有准备好的情况下显示。如果有需要,您的任务就是准备这些服务,以处理在闪电体验范围内的要求。正如我们之前所说,细节有所不同,所以我们不能在这里提供具体的答案。

有一件事我们特别要提的是会话维护。我们这里所说的“会话”基本上就是您的浏览器从请求到请求重用的一种令牌,这样您就不必为每个请求输入用户名和密码。您经常需要使用全局变量$ Api.Session_ID访问当前会话。

这是要记住的事情。 $ Api.Session_ID根据请求的域返回不同的值。这是因为每当您跨越主机名边界(例如.salesforce.com到.visual.force.com)时,会话ID都会在会话期间发生变化。通常情况下,Salesforce会透明地处理域之间的会话切换,但是如果您要传递会话ID,请注意,您可能需要从正确的域重新访问$ Api.Session_ID以确保有效的会话ID。

Lightning Experience和Visualforce页面不仅保存在不同的浏览器上下文中,而且也来自不同的域。因此,尽管它全部显示在一个浏览器窗口中,但Visualforce iframe中的会话ID将不同于iframe之外的会话ID,而在Lightning Experience的另一部分中。 Salesforce和Lightning Experience在正常使用情况下处理此透明。但是如果你在派对上通过会议ID(通常不是一个好主意),你可能需要回顾一下你是如何处理它的。

范围影响

当我们谈论范围时,我们主要谈论以下几种事情。

  • DOM访问和修改
  • JavaScript范围,可见性和访问
  • JavaScript全局变量,如window.location

如果这个列表听起来很复杂或者令人困惑,不要担心,我们可以把它归结为简单易记的东西:不要碰别人的东西。具体而言,您的JavaScript代码(以及样式表规则)可能会影响页面浏览上下文中的元素(DOM节点,JavaScript变量等),但无法访问任何其他浏览上下文中的元素,闪电体验上下文。不要触摸其他上下文的东西!

实际上,你想要做这种事情的最常见的代码模式是操纵window.location导航到另一个页面。这是一个很常见的事情,我们已经写了关于这个特定问题的细节……当你完成这个模块的时候,你会厌倦听到这个问题,我们保证。

最后一个音符如果您是一位经验丰富的JavaScript开发人员,您可能已经在考虑通过使用contentWindow,window.parent等来了解如何处理“我无权访问父浏览上下文”问题。请不要。你可能会遇到同源策略(Visualforce和Lightning Experience来自不同的领域,请记住?)。即使你不这样做,你可能会用明显的,间歇性的错误代替显而易见的错误。你想在哪里花时间:做正确的事情,还是调试?

做正确的事情意味着调用我们在Visualforce页面中提供的API,主要用于导航。如果您确实需要跨越边界影响事物,请使用window.postMessage将消息发送到另一个帧中的接收代码。

Visualforce默认值和闪电体验的环境变化

当您的Visualforce页面在Lightning Experience中运行时,幕后会发生许多低级别更改。这些改变使得大多数页面在Lightning Experience容器中“正常工作”,有时你可以为他们在那里感到高兴。但是你仍然想知道他们正在发生,特别是当你在处理高级应用程序流时,或者解决一个棘手的问题时。
其中一些变化很简单,一旦你想到它们,就很明显。例如,在Lightning Experience中运行的Visualforce页面始终具有标准的Salesforce Classic标题和侧栏。其他变化并不明显,但同样有很大的影响。

<apex:page> showHeader和侧栏属性始终为false

这些属性会影响Visualforce页面上的Salesforce Classic标题和侧边栏。在Lightning Experience中运行页面时,Salesforce Classic标题和侧栏会始终被抑制,以支持Lightning Experience导航元素。没有相应的属性可以影响Lightning Experience标题或侧边栏,因为它们不能被抑制。
如果您的页面在Salesforce Classic和Lightning Experience之间共享,则仍然可以将这些属性设置为在Salesforce Classic中运行页面时要使用的值。

注意

确定是否包含或取消标准Salesforce Classic样式表的<apex:page>的standardStylesheets属性不受Lightning Experience的影响。也就是说,在Lightning Experience中它默认为true,但是你可以改变它。

sforce.one JavaScript工具对象

尽管sforce.one听起来像一个在Salesforce cantina中工作的机器人,但它实际上是一个实用程序对象,它提供了许多有用的功能,您可以在自己的JavaScript代码中使用这些功能。
在Lightning Experience或Salesforce应用程序中运行时,sforce.one会自动注入您的页面。您将在您的JavaScript调试器控制台和Web开发人员资源列表中看到它。没有什么需要添加的,也没办法压制它。 (可惜的是,在Salesforce Classic的Visualforce页面中无法获取sforce.one。)

sforce.one主要用于消除导航事件。完整的细节在即将到来的单位,管理导航。

____________________

*没有Salesforce酒吧。唉。

Visualforce和闪电体验 – 开发Visualforce页面以获得闪电体验

学习目标

完成本单元后,您将能够:

  • 完成Lightning Experience开发环境的设置。
  • 描述在开发过程中查看Lightning Experience中Visualforce页面的两种不同方式。
  • 描述在开发过程中预览Visualforce页面和正式测试该页面的区别。
  • 创建一个测试矩阵,描述在对Visualforce页面进行正式测试时需要包含和测试的不同因素。

为闪电体验开发Visualforce页面

为Lightning Experience创建Visualforce页面和应用程序的开发过程在某些方面与Salesforce Classic的开发有很大的不同。在其他人中,你会发现它是一样的。主要区别在于您在开发过程中如何查看和测试您的页面。
在本单元中,我们将介绍设置开发环境的细节,然后介绍在构建过程中测试页面的“正确”方式的细节。好消息是,您需要使用Lightning Experience进行开发的过程与用于开发Salesforce移动页面的过程相同。

设置您的编辑器

您要设置的第一件事就是您将用于编写代码的编辑工具。无论您是为Lightning Experience,Salesforce Classic还是Salesforce应用程序创建页面,以及是否使用Developer Console,Force.com IDE或旧的安装编辑器,此过程都保持不变。
如果您已经有了首选的Visualforce编辑工具,则无需在此处执行任何操作。编写和保存您的Visualforce标记仍然完全相同。开发者控制台拥有自己的用户界面,在Lightning Experience和Salesforce Classic之间不会改变。安装程序中的编辑器也保持不变,在所有用户界面上下文中保留Salesforce Classic用户界面。当然,如果您使用的是本地工具(如Force.com IDE或许多第三方工具中的一种),则这些工具都有自己的用户界面。

一个例外是Visualforce开发模式页脚中的编辑器。如果您已经在用户设置中启用了开发模式,并且正在使用Salesforce Classic,那么使用开发模式页脚查看和编辑Visualforce页面的方式与您所期望的相同。如果您切换到Lightning Experience,然后使用传统的https://yourInstance.salesforce.com/apex/PageName URL模式访问页面,则可能会惊讶于在Salesforce Classic中找回自己。

这是预期的,当我们查看和测试您的Visualforce页面时,我们会进一步讨论它。现在,请了解Visualforce的开发模式仅适用于Salesforce Classic。

在开发过程中查看Visualforce页面

在开发Visualforce页面的同时查看是一个常见任务。虽然它不是正式意义上的“测试”,但是您当然希望能够与您所建立的功能进行交互,以确保正确的行为正在取得进展。这通常通过使用https://yourInstance.salesforce.com/apex/PageName URL模式访问页面来完成。虽然这仍然适用于审阅Salesforce Classic中的页面,但它不适用于检查Lightning Experience中的行为。
无论您的用户界面设置如何,您使用直接URL访问查看的页面都始终显示在Salesforce Classic中,也就是说,“经典”Visualforce容器。如果您创建具有Lightning Experience特定行为的Visualforce页面,则仅使用通常的直接URL访问权限就无法查看该行为。

超越基础

幕后造成这种情况的是什么?这很简单,真的。为了在Lightning Experience中查看您的页面,您需要访问Lightning Experience容器应用程序。这意味着访问/one/one.app。如果您正在访问,则无法访问/ apex / PageName。他们只是两个不重复的网址。

那么开发人员要做什么?您需要从Lightning Experience应用程序本身查看您的页面,以便它在Lightning Experience容器内运行。这意味着您需要导航到Lightning Experience中的页面,并且有多种方法可以做到这一点。

获取特定Visualforce页面的最简单方法是为其创建一个选项卡,然后通过应用程序启动器中的所有项目部分导航到该选项卡。一个更长远的方法是创建一个“In Development”应用程序,并在您处理它们时添加Visualforce标签,并在它们转入生产时移动或移除它们。由于这样做的控制已经移动了一下,下面是简短的说明。

  1. 从设置中,在快速查找框中输入应用程序,然后选择应用程序管理器。
    您应该看到Lightning Experience App Manager设置页面。
  2. 点击New Lightning App,然后在开发中为您的页面创建一个自定义的应用程序。
    考虑限制您的应用程序仅限于系统管理员,或者您为组织中的开发人员创建的配置文件。Assign app to limited profiles to control access

    您不需要用户在用户界面中将其添加到永久位置之前查看您的页面。

  3. 从设置中,在快速查找框中输入应用程序菜单,然后选择应用程序菜单。

    你应该看到应用程序菜单设置页面。

  4. 确保您的In Development应用程序在应用程序启动器中设置为可见。

    当你在这个时候,你可能想重新排列项目,甚至隐藏你不使用的应用程序。

    App Launcher app visiblity and order
  5. 从设置中,在快速查找框中输入标签,然后选择标签。

    您应该看到自定义选项卡设置页面。

  6. 在“Visualforce选项卡”部分中单击“新建”,然后为当前正在开发的页面创建一个自定义选项卡。

    使该选项卡仅可见于您的开发用户配置文件,并将该选项卡仅添加到您的In Development应用程序中。

    Make in development tabs only visible to developers
    Add tab to In Development app
  7. 对要添加到In Development应用程序中的每个页面重复上一步骤。为了将来添加新的页面,这是唯一需要的步骤。

尽管如此,在您处理页面的过程中,您可以轻松查看自己的页面,但与仅将网页名称输入到URL中并不相同。对于在Lightning Experience中测试页面的开销相似的方式,您可以在JavaScript控制台中键入以下内容:

$A.get("e.force:navigateToURL").setParams(
    {"url": "/apex/pageName"}).fire();
这个JavaScript触发了Lightning Experience的navigateToURL事件,相当于输入了经典的/ apex / PageName的URL – 你甚至可以在代码中看到这个URL模式。

注意

您目前需要使用Lightning Experience才能使用此技术。如果您使用的是Salesforce Classic,则JavaScript代码将失败。

为了使用起来更方便一些,请将以下小书签添加到浏览器的菜单或工具栏中。 (为了便于阅读,我们封装了这些代码。)

javascript:(function(){ 
    var pageName = prompt('Visualforce page name:'); 
    $A.get("e.force:navigateToURL").setParams(
        {"url": "/apex/" + pageName}).fire();})();
这个小书签提示您输入页面名称,然后触发事件直接导航到它。有用!
导航到正在处理的页面后,只需使用浏览器的重新加载命令即可在进行更改时刷新页面。

在多个环境中查看Visualforce页面

如果您正在创建将在Lightning Experience,Salesforce Classic和Salesforce应用程序中使用的页面,那么您需要在所有环境中查看这些页面。为此,您需要在多个浏览器和多个设备上打开该页面。
将在不同的Salesforce用户界面上下文中使用的Visualforce页面和外观因素在开发过程中很难进行审阅。您可以使用配置文件菜单中的环境选择器在Salesforce Classic和Lightning Experience之间来回切换,但这种情况会很快变老。您也可以使用浏览器的用户代理设置来模拟Salesforce移动环境,但这更麻烦。

相反,您将要使用多个浏览器甚至多个设备来查看您的页面。而且您还希望至少可以访问另外一个测试用户。以下是如何设置开发环境的示例。

主要发展环境
此环境是您在安装程序中对组织进行更改的位置,例如添加自定义对象和字段,也可能是编写实际代码的位置(如果使用开发人员控制台)。

  • 浏览器: Chrome
  • 用户:您的开发人员用户
  • 用户界面设置:Salesforce Classic
在此环境中查看您的页面在Salesforce Classic中的设计和行为。
闪电体验评论环境
这个环境是你在Lightning Experience中检查你的页面设计和行为的地方。

  • 浏览器:Safari或Firefox
  • 用户:您的测试用户
  • 用户界面设置:闪电体验
Salesforce移动审查环境
此环境用于检查您的页面在Salesforce应用程序中的设计和行为。

  • 设备:iOS或Android手机或平板电脑
  • 浏览器:Salesforce应用程序
  • 用户:您的测试用户
  • 用户界面设置:闪电体验

注意

这只是一个示例设置,您可以使用Salesforce Classic和Lightning Experience中的任何现代浏览器或移动设备。关键是要使用两种不同的浏览器,以便您可以同时访问Salesforce Classic和Lightning Experience,并使用实际设备来测试Salesforce应用程序。

这可能听起来相当复杂,初始设置起来有点麻烦,特别是如果你正在寻找编码的话。但请记住两件事。首先,一旦你成立,就完成了。其次,这个工作区不仅为您提供了一个很好的开发环境,还为您提供了正式测试页面所需的环境。因为你不会梦想在没有经过正式测试的情况下将网页投入生产,对吗?

测试您的Visualforce页面

这只是一个示例设置,您可以使用Salesforce Classic和Lightning Experience中的任何现代浏览器或移动设备。关键是要使用两种不同的浏览器,以便您可以同时访问Salesforce Classic和Lightning Experience,并使用实际设备来测试Salesforce应用程序。

这可能听起来相当复杂,初始设置起来有点麻烦,特别是如果你正在寻找编码的话。但请记住两件事。首先,一旦你成立,就完成了。其次,这个工作区不仅为您提供了一个很好的开发环境,还为您提供了正式测试页面所需的环境。因为你不会梦想在没有经过正式测试的情况下将网页投入生产,对吗?

测试您的Visualforce页面
测试您的Visualforce页面,然后将其部署到生产环境中是一项重要的开发任务。当您的组织采用Lightning Experience时,测试页面的过程变得更加复杂。
我们刚刚讨论了在开发页面时需要设置的环境,以进行快速,非正式的测试。这些环境的需求也适用于正式测试您的网页和应用程序。让我们来谈谈为什么你需要这些不同的环境,而不是重复它们。

在Lightning Experience和Salesforce Classic中测试页面的需求相当明显,但为什么不能在同一个浏览器中使用相同的用户来测试?事实上,你可以,你应该。您的用户可以在不同的用户界面之间来回切换,并且您应该确认您的页面在这些用户界面中工作。

但是,您也希望以更加独立和系统的方式来测试页面,以确保您正在测试的是页面的基本功能,尽可能与其他代码的效果分离,不管代码是否属于您,我们的,浏览器的,或者设备的。

这突出了另一个测试问题。在过去,我们建议您在台式机或笔记本电脑上进行Salesforce移动开发以及导航到Salesforce应用使用的/one/one.app URL是合理的。此方法不再有效,因为/one/one.app由Salesforce应用程序和Lightning Experience共享,具体取决于连接到它的设备。虽然你可以通过更改浏览器的用户代理来欺骗/one/one.app,但这是一个坏主意,反模式。原因是,即使是来自同一供应商的台式机和移动浏览器的行为也有所不同,有时甚至会有所不同。除非您正在测试每个设备和您计划支持的每个浏览器,否则无法进行严格的正式测试。

如果你正在开发一个单独的页面,或者一个基本的应用程序相同的设备,你的“矩阵”的不同因素可能很简单。但对于更有雄心的项目,如果您正在开发需要在各种可能性范围内支持的功能,那么您的测试计划应该考虑跨越测试的需求:

  • 每个不同的支持设备。
  • 每个不同的支持的操作系统
  • 每种不同的支持浏览器 – 包括嵌入自己的Salesforce应用程序。
  • 每个不同的受支持的用户界面上下文(Lightning Experience,Salesforce Classic和Salesforce应用程序)。

幸运的是,为了您的理智,其中一些因素一起崩溃,减少了组合爆炸。例如,大多数的苹果移动设备可以指望更新到最新版本的iOS。这意味着设备,操作系统和浏览器实际上只是一个组合。因此,您的测试计划可能会选择仅测试一个iPhone和一个iPad,并更新到最新的iOS和Salesforce应用程序。

关于测试的最后一句话。我们强烈建议您的开发和测试环境相似的另一个原因是,您可以在开发过程的早期开始测试和全面测试。我们发现,直到项目后期才开始对辅助设备进行测试。当发生这种情况时,发现问题时不可避免地会受到挫折。

提前测试,经常测试,测试一切。

Visualforce和闪电体验 – 在Lightning Experience中使用Visualforce

学习目标

完成本单元后,您将能够:

  • 在Lightning Experience中使用它们之前,确定两个关于Visualforce页面的高级事项。
  • 在Lightning Experience中列出至少五个可以使用Visualforce的地方。

在Lightning Experience中使用Visualforce

Lightning Experience为您的Salesforce组织带来全新的用户界面,但这并不意味着您的Visualforce应用程序停止工作。 Visualforce页面在Lightning Experience中工作,许多没有任何修改。事情已经移动了,而且还有一些琐事需要完成,以确保您的Visualforce页面以您期望的方式工作,因为您的用户可以在Lightning Experience和Salesforce Classic之间切换。而且有很少的功能,唉,在闪电体验中不起作用。我们会在这个模块中把它分类到所有的东西上。
我们从几个基本的细节开始。这些是我们稍后会深入讨论的主题,但是我们先来处理一些重要的项目。
  • 除了一些重要的例外情况,Visualforce在Lightning Experience中“正常工作”。如果您已经为您的组织编写了Visualforce应用程序,则无论您的用户是在Lightning Experience还是Salesforce Classic中访问这些应用程序,都可以期待它们的正常工作。
  • 如果您的Visualforce页面使用内置的标准组件,则其外观与Salesforce Classic相匹配,无论您的用户是在Lightning Experience还是Salesforce Classic中访问它们。如果您希望自己的页面与Lightning Experience风格相匹配,则需要完成一些工作。
    如果您的Visualforce页面使用JavaScript,则需要检查一些内容。在Lightning
  • Experience中显示时,Visualforce不会“拥有”整个页面,因为您的JavaScript代码需要按照一些新规则进行播放。
  • 在Lightning Experience内部运行时,Visualforce的运行方式还有一些变化。在大多数情况下,这些都是转向“正常工作”的曲柄,但是你会想要知道它们都是一样的。

最后,我们提到有些事情已经移动了吗?他们曾经! Lightning Experience是一个对如何使用Salesforce的完整反思,虽然这项工作还没有完成,但是我们对我们要去的地方感到非常兴奋。为了让您的Visualforce在新环境中的位置得到定位,我们来快速浏览一下在Lightning Experience中可以使用Visualforce的地方。

你可以在Lightning Experience中使用Visualforce

与Salesforce Classic一样,您可以使用自定义的Visualforce页面和应用程序来扩展Lightning Experience。但是,如果你发现它们已经改变,并且还有一些地方你不能把Visualforce。
以下是您可以将Visualforce添加到Lightning Experience组织的一些方法。不过,这只是一个快速浏览。有关如何使用Visualforce页面自定义组织的更多详细信息,请参阅本机末尾的资源。

从应用启动器打开一个Visualforce页面

您的Visualforce应用程序和自定义选项卡均可从应用程序启动器获得,您可以通过单击标题中的应用程序启动器图标App Launcher icon来访问该应用程序。
App Launcher apps and tabs

点击一个自定义的应用程序(1)来激活它。应用程序中的项目会显示在导航栏中,包括您添加到应用程序的任何Visualforce选项卡。请注意,您需要将Visualforce页面添加到选项卡,以便在应用启动器中访问它们。所有项目(2)中均可找到不在应用程序中的Visualforce选项卡。

将一个Visualforce页面添加到导航栏

(嘿,“ForceUI”实用程序页面听起来有趣吗?请继续阅读本模块!)

在标准页面布局中显示Visualforce页面

通过在其上嵌入Visualforce页面来扩展页面布局,以在标准页面上显示完全自定义的内容。除了您需要查看记录的详细信息以查看页面布局之外,此处的行为与Salesforce Classic相同。

Visualforce on a Lightning Experience page layout

在Lightning App Builder中添加Visualforce页面作为组件

在Lightning App Builder中创建自定义应用程序页面时,可以使用Visualforce组件将Visualforce页面添加到页面。

Add a Visualforce page to a Lightning App Builder page

注意

您必须为“闪电体验”,“Salesforce应用”和“闪电社区”启用Visualforce页面才能使其在Lightning App Builder中可用。

启动Visualforce页面作为Quick Action

Global action in Lighning Experience
虽然他们在Lightning Experience用户界面中的位置与Salesforce Classic大不相同,但添加快速操作的过程大致相同。将它们添加到对象页面布局上的相应发布者区域。
将快速操作添加到页面布局

Adding quick actions to a page layout

通过覆盖标准按钮或链接来显示Visualforce页面

您可以使用Visualforce页面覆盖对象上可用的操作。 当用户单击已被覆盖的按钮或链接时,将显示页面而不是标准页面。 设置这个与Salesforce Classic非常相似。 事实上,在定义一个动作覆盖的时候,你很难说出你正在使用Lightning Experience。

Override the Edit action on Contact object