已知的 Visualforce Mobile 问题

Salesforce 发布已知问题以增强信任并支持客户成功。

Salesforce 客户支持和工程部门自行决定发布已知问题 根据客户报告的数量、问题的严重性以及 解决方法。如果您遇到的问题未列出,则它可能不符合以下条件 在已知问题网站上发布。并非所有已知的 bug 都会发布;通常 bug 会得到解决 快速或不影响客户。

  • 访问或权限问题 访问和权限问题
    会影响用户在 Salesforce 应用程序中看到的页面和记录。
  • 设备传感器问题 设备传感器问题包括移动设备的摄像头、麦克风和地理位置问题
  • 输入问题
    输入问题会影响用户使用 Salesforce 移动应用程序中的输入字段和选择器输入信息的方式。
  • 加载和性能问题 加载和性能问题
    会影响 Salesforce 移动应用程序的响应速度和加载速度。
  • 导航问题
    这些问题会阻止用户导航到 Salesforce 移动应用程序中的某些页面。
  • 网络问题 网络问题
    会影响 Salesforce 移动应用程序的连接。
  • Salesforce Classic 与 Lightning Experience 问题
    这些问题是由 Salesforce Classic 和 Lightning Experience 之间的切换引起的。
  • 更新记录问题
    这些问题会影响尝试在 Salesforce 移动应用程序中更新记录的用户。
  • 用户界面问题
    这些问题会影响 Salesforce 移动应用程序的用户界面。

访问或权限问题

访问和权限问题会影响用户在 Salesforce 应用程序。

问题溶液
如果在 用户配置文件级别,用户无法访问 Visualforce 内容。而不是 Visualforce 内容, 用户会看到错误消息“您无法查看此页面,因为您没有 权限,或者因为该页面在移动设备上不受支持。本期独有 适用于 iOS 的 Salesforce 和适用于 Android 的 Salesforce。在用户配置文件上禁用高确定性,然后重新登录。在以下位置实现高保证 Salesforce 连接的应用程序级别,而不是用户配置文件级别,以继续强制执行 多重身份验证。
Experience Cloud 站点用户无法在转换操作中访问 Visualforce 覆盖 对于应用程序中的潜在客户。相反,他们会看到错误消息“您也无法查看此页面 因为您没有权限,或者因为该网页在移动设备上不受支持 设备。创建一个单独的 Visualforce 操作,用于使用相同的 Visualforce 转换潜在客户 页。

设备传感器问题

设备传感器问题包括移动设备的摄像头、麦克风和 地理位置。

问题溶液
移动设备的相机在输入字段的子浏览器窗口中不起作用。 相反,用户会看到黑屏。这个问题可能是 Apple 的错误,用于儿童浏览器 窗户。此问题仅适用于 iOS 版 Salesforce。SFSafariViewController在 Safari 移动浏览器中打开 Salesforce,方法是点击 Safari 中的图标 Salesforce 移动应用程序中子浏览器窗口的右下角。

输入问题

输入问题会影响用户如何使用 Salesforce 移动应用程序。

问题溶液
将显示使用 URL 内容源的列表按钮访问的 Visualforce 页面 输入选择器的样式不正确。例如,输入日期字段显示一个日历,其中 白底白枣。此问题仅适用于 Android 版 Salesforce。将列表视图 URL 按钮转换为具有 Visualforce 页面内容的列表视图按钮 源、Visualforce 选项卡或 Visualforce 操作。
如果用户点击输入字段,iOS 本机输入控件将保留在屏幕上 然后,标题后退箭头仍然激活这些控件。输入控件还可以 导航到其他页面时意外重新出现。此问题是 Salesforce 独有的 适用于 iOS。在 Salesforce 移动版中导航之前,请确保输入控件已关闭 应用程序。
在字段中长按后,Visualforce 输入字段冻结或不允许输入。 用户可以长按复制和粘贴、进行选择或更改光标位置。这 问题仅适用于 iOS 版 Salesforce。将以下 JavaScript 行添加到 Visualforce 页面的底部:window.onkeydown=function(){window.focus();}

加载和性能问题

加载和性能问题会影响 Salesforce 移动应用程序的响应速度,以及 加载速度有多快。

问题溶液
如果将 Visualforce 页面或 Lightning 选项卡设置为登录页面,则可能存在页面 加载错误和性能下降。错误消息“我们在加载时陷入了循环 该页面“或”加载此页面需要一段时间。您可以继续等待或重试” 出现。选择一个标准选项卡作为登录页面。
打开多个文件会导致 iOS 版 Salesforce 冻结。在 Safari 中使用 Salesforce 移动 Web。

导航问题

这些问题会阻止用户导航到 Salesforce 移动版中的某些页面 应用程序。

问题溶液
Visualforce 选项卡会在用户离开后加载登录页面。在切换应用或选择其他选项卡之前允许页面完全加载,或者选择 再次打开 Visualforce 页面选项卡。
用户在切换后返回 Canvas 页面时可能会看到空白页面 应用程序。重新加载 Canvas 应用。
如果发布者操作使用该函数对文件记录进行导航调用,则文件预览 窗口可能会在显示文件之前关闭。出现此问题的原因是该方法在导航调用之前触发 文件记录。此问题仅适用于 iOS 版 Salesforce。sforce.one.navigateToSObjectpublisher.close不要使用之前的通话 导航到文件记录。用户必须在以下时间后手动关闭发布者操作窗口 他们已完成对文件记录的处理。publisher.close
当用户强制退出应用时,记录类型选择页可能会显示不正确 从记录类型选择页面的正确版本。本期独有 适用于 iOS 的 Salesforce。导航回对象主页,然后再次点击新建。如果 问题仍然存在,请清除应用程序缓存或注销以重置行为。
使用导航到 iPad 上的对象主页。出现错误后,没有其他导航调用可以处理 页面,直到设备缓存被清除。清除缓存。
使用导航库从 Visualforce 页面按 ID 导航到笔记记录,然后点击取消或 保存会导致循环。如果此导航方法是从 Visualforce 操作调用的 记录详细信息页面,则“取消”、“保存”和“返回”按钮可能会返回到空白记录详细信息页面。sforce.one没有直接的解决方法。强制退出并重新启动应用程序。
视图状态 POST 请求存储在 Salesforce 移动应用程序导航历史记录中。 如果用户提交视图状态表单,导航到另一个 Visualforce 页面,然后单击 后退按钮,将再次处理 POST 请求。此问题会在 适用于 iOS 的 Salesforce,并导致浏览器应用程序中出现错误。

网络问题

网络问题会影响 Salesforce 移动应用程序的连接。

问题溶液
网络连接错误消息“请检查您的网络连接,然后重试” 当网络处于活动状态时,显示在 Visualforce 页面上。本期独有 适用于 iOS 的 Salesforce。关闭组织范围的设置“在 Salesforce 中启用缓存”。

Salesforce Classic 与 Lightning Experience 问题

这些问题是由 Salesforce Classic 和 Lightning 之间的切换引起的 经验。

问题溶液
UI 检查错误地返回,而不是在用户使用 移动设备上的经典 UI。Visualforce 全局和 Apex 类命令会出现此问题。Theme4tTheme3$User.UIThemeDisplayedUserInfo.getUiThemeDisplayed通过验证 JavaScript 对象是否可用来检查用户的当前 UI;此对象在 经典 UI。sforce.one

更新记录问题

这些问题会影响尝试在 Salesforce 移动版中更新记录的用户 应用程序。

问题溶液
用户无法在更新后立即保存 Salesforce 记录。相反 他们会看到错误消息“记录在编辑期间被 [当前用户] 修改 会期。记下您输入的数据,然后重新加载记录并输入您的更新 再次”。避免在立即调用 标准编辑页面。否则,用户必须等待 30 秒,直到缓存期过去, 在他们能够编辑记录之前。
编辑未读线索时会触发冲突检测。错误消息“这 记录在编辑会话期间被(用户更新潜在客户)修改。记下 您输入的数据,然后重新加载记录并再次输入您的更新”。打开记录并使用记录详细信息中的编辑按钮进行更改 页。
当 可选参数在 以下命令:.错误消息“查看此页上的错误。记录类型 ID: 此值对用户无效:可能会显示“[用户名]”。recordTypeIDrecordTypeIDsforce.one.createRecord(​entityName​[, recordTypeId]);修改对 要传入参数的 Visualforce 页面。sforce.one.createRecordrecordTypeId

用户界面问题

这些问题会影响 Salesforce 移动应用程序的用户界面。

问题溶液
Salesforce 移动应用程序标准后退导航按钮仅在点击时才会响应 两次。当编程调用(如 和)首先用于导航回一个页面,然后导航回用户时,会出现此问题 尝试使用标准的“后退”按钮返回另一页。本期独有 适用于 iOS 的 Salesforce。window.history.back()sforce.one.back()如果您的实现有多个页面,请将其设计为仅使用标准背面 按钮或仅编程调用。
当用户从记录详细信息页面中嵌入的 Visualforce 页面单击返回时, 页面不滚动。单击“返回”后等待几秒钟,离开记录并返回,或者 将设备从横向旋转到纵向。
某些 CSS 元素会导致 CancelPost 或 Save 按钮,或 用户界面,变得无响应。删除这些影响滚动的 CSS 元素:overflow-x: hidden;overflow-y: scroll;-webkit-overflow-scrolling: touch;
用户无法在 Salesforce for iOS 中创建和编辑页面的标准记录上滚动。 用户通常只有在链接到“创建”的 Visualforce 页面时才会遇到此问题 或“编辑”页面包含超出设备屏幕的内容。本期独有 适用于 iOS 的 Salesforce。减少 Visualforce 页面上包含“创建”或“编辑”的内容量 链接,以便用户无需在自定义页面上滚动
对象页面布局中嵌入的 Visualforce 页面不遵循用户定义的 高度。此问题仅适用于 iOS 版 Salesforce。从页面中取消选择嵌入式 Visualforce 页面上的显示滚动条选项 布局编辑器。
在 Safari 中滚动 Visualforce 页面时,页面会移动,但不会显示任何内容 新文本。此问题是 Apple 的错误。此问题仅适用于 iOS 版 Salesforce。UIWebView刷新页面。
Experience Cloud 站点用户会看到对象的标准新建按钮,即使页面 被 Visualforce 操作覆盖隐藏,并标记为不适用于移动设备。本期 是 iOS 版 Salesforce 独有的。没有已知的解决方案。在 Safari 中使用基于浏览器的 Salesforce 版本 iOS系统。
使用 Lightning 组件对对象进行视图覆盖会禁用滚动 通过父对象的相关列表访问时的整个页面。本期独有 适用于 iOS 的 Salesforce。没有已知的解决方案。通过对象主页选项卡或其他方式访问记录 手段,例如程序化导航。

在 Salesforce 中使用 Visualforce 的注意事项和限制 移动应用

Visualforce 允许开发人员构建复杂的自定义用户界面,这些用户界面可以 原生托管在闪电网络上。Visualforce 是 Salesforce 久经考验的模型, 使开发人员能够访问数据以及强大的工具和功能。有很多好处 在 Salesforce 移动应用程序中使用 Visualforce,但也有一些限制。

可用性

  • 易于实施,可提高生产率。
  • 以页面为中心的模型自然而然地将大型应用程序拆分为可管理的小页面。

与 Salesforce 平台和其他工具集成

  • 访问 Salesforce 丰富的元数据基础架构。
  • 标准控制器允许直接访问对象,也可以通过关系访问对象,而无需 执行单个查询。
  • Visualforce 页面可以充当 JavaScript 或第三方框架的容器,例如 AngularJS 或 React。

定制

  • 标准选项卡、自定义对象选项卡和列表视图,这些选项卡被 Visualforce 覆盖 页面在 Salesforce 移动应用程序中不受支持。移动用户将看到默认的 Salesforce 对象的页面 相反。

互动

  • 有限的交互性(除了您自己添加的 JavaScript 功能)。
  • 难以打造身临其境的用户体验。

速度

  • 延迟较高,这会降低移动性能。
  • 与计算能力有限的低端或较旧的移动设备不匹配 资源。
  • Visualforce 在 Salesforce 服务器上处理标记标签,从而提高响应速度 时间。

one.app 容器

在 Salesforce Classic 中,Visualforce “拥有”页面, 请求和环境。Visualforce 是应用程序容器。但是在Salesforce中 移动应用程序和 Lightning Experience,Visualforce 在较大的 /lightning 容器内的 iframe 内运行。如果您习惯于在 Salesforce Classic 中进行开发,则使用 one.app 容器需要进行一些调整,主要是范围和安全注意事项。查看更多 信息,请参阅了解 Salesforce 移动应用程序 容器。

针对 Visualforce 页面问题准备支持请求 Salesforce 应用程序

Salesforce 提供资源来帮助开发人员找到问题的答案,并 解决他们的问题。我们建议您先看一下开发者论坛, Salesforce Stack Exchange 和“已知问题”页面,查看您是否可以立即找到 解决您的问题。如果您的问题仍未得到解答,您可以将案例提交至 Salesforce 的支持团队,他们会将您的问题发送给最佳人选来回答 它。

Salesforce 开发人员论坛

Salesforce 开发人员社区的论坛是任何 有关Salesforce平台和工具的问题。在以下社区中提问和回答问题 400 万 Salesforce 开发人员。

Salesforce 堆栈交换

Salesforce Stack Exchange 是面向 Salesforce 管理员的问答网站, 实施专家和开发人员。任何人都可以提出和回答问题。

已知问题

Salesforce 发布已知问题,通过提供以下功能来增强信任和客户成功 对已知 bug 的可见性。Salesforce 客户支持和工程发布已知 基于客户报告数量、问题严重性和 变通办法的可用性。并非所有已知的 bug 都符合发布条件。

提交支持请求

如果您在论坛上找不到问题的答案,请 Stack Exchange 或“已知问题”页面,下一步是提交支持案例。

  1. 在“帮助和培训”门户上登录您的帐户。
  2. “联系支持人员”磁贴下,单击“创建” 案例
  3. 在“帮助查找器”页面上,选择“开发”,然后选择“Apex/Visualforce”。
  4. 在“问题”选项卡上,检查您的问题是否包含在常见问题中 问题和答案。如果没有,请按 Log a New Case 图标 页面底部。

提交案例需要以下信息:

  • 用户名
  • 首选电子邮件地址
  • 电话号码
  • 时区
  • 大体时间
  • 回电日期
  • 业务影响

为了帮助 Salesforce 的专家快速解决您的案例,请总结重现的步骤 “说明”框中的错误。使步骤尽可能清晰具体。提供 演示该问题的最简单、最短的代码示例。通常,开发人员会解决 他们在简化繁殖过程中的问题。

此外,请考虑向 Salesforce 支持团队授予登录访问权限,以帮助他们进行调查 你的情况。要授予登录访问权限,请转到您的姓名/设置/我的个人信息/授予登录访问权限/选择 Salesforce.com 支持

检查支持请求

您可以查看已提交的支持案例的进度。

  1. 在“帮助和培训”门户上登录您的帐户。
  2. 在“我的成功中心”磁贴下,单击“转到”。
  3. 单击左侧导航栏中的“支持案例”。

选择有效的页面布局

设计在 Salesforce 移动版中美观且运行良好的 Visualforce 页面 应用程序,使用适合使用页面的上下文的页面布局。添加的页面 作为主导航选项卡或操作栏中的自定义操作,几乎可以使用完整的 屏幕,并且可以垂直滚动,而 Visusalforce 添加到 对象的页面布局必须适合特定的有限空间。

一般来说,添加到页面布局的 Visualforce 在只读的情况下效果最好。 信息一目了然。放置需要用户交互的功能,例如多字段 表单,在全屏页面上,通过将它们添加为主导航中的选项卡或自定义 操作栏中的操作。

页面布局上的 Visualforce

添加到对象页面布局的 Visualforce 页面将显示在记录中 详细信息页面。您可以控制 Visualforce 元素在 移动记录详细信息屏幕,将字段和其他记录详细信息放在上面,并且 在它下面,通过更改其在对象页面布局上的位置。视觉力 以这种方式添加的页面遵循相同的规则来对字段和其他 元素确实如此。

注意

本页图片来自上一页 Salesforce 移动应用程序,而不是新的 Salesforce 移动应用程序。

  1. 加载记录时会显示记录标头,但可以向上滚动 并由用户离开屏幕。在屏幕上时,它总共有 158 像素高 设备,并占用屏幕的整个宽度。你无法控制 显示记录标头。
  2. 记录控件和详细信息,由 Salesforce 自动生成 移动应用程序。
  3. 添加到对象页面布局的 Visualforce 页面。
  4. 将宽度设置为 100%;元素自动调整大小,减去一些填充 在两边。
  5. 通过设置 页面布局编辑器中项目的高度(以像素为单位)。视觉力 元素正好使用该高度,即使内容较短。在那 情况下,额外的区域是空白的。如果页面内容较高,则 内容被剪裁。最佳做法是,不要设置内联 Visualforce 页面要比您打算的最小设备屏幕高 支持。

虽然您可以将多个内联 Visualforce 页面添加到页面布局中,但它可以快速 成为滚动浏览它们以查看页面其余部分的用户体验挑战。 最佳做法是永远不要在 一排;将 Visualforce 元素与常规页面元素(例如字段)分开。 如果您需要全屏显示页面,请考虑将其移至自定义页面 操作。添加到页面布局的 Visualforce 页面会自动具有普通的 Salesforce 删除了标题和侧边栏。您可能会发现显式地将它们和 在开发页面时,完整的 Salesforce 站点样式表会关闭。 此外,如果您的网页使用 Google Maps API,Google 建议使用 HTML5 文档类型。下面是一个执行所有这些操作的标签 事情:

<apex:page>

<apex:page standardController="Warehouse__c"
    docType="html-5.0" showHeader="false" standardStylesheets="false">

全屏布局

添加到 Salesforce 移动应用程序导航菜单或自定义的 Visualforce 页面 动作到动作栏,几乎可以使用整个屏幕,允许更多 信息,以及更复杂的用户界面。

注意

本页图片来自上一页 Salesforce 移动应用程序,而不是新的 Salesforce 移动应用程序。

  1. 提供对主导航菜单的访问的 Salesforce 标头是42像素高。 标头的内容无法更改。
  2. 设备屏幕的其余部分专用于您的 Visualforce 页面。

在 Salesforce 移动应用程序中显示时,标准 Salesforce 标头和 侧边栏会自动删除。但是,用作自定义操作的 Visualforce 页面 与完整的 Salesforce 站点共享,并将页面添加到 导航可能会共享,也可能不会共享。与完整 Salesforce 站点共享的页面 不应明确删除标准的 Salesforce 标题和侧边栏,除非 删除标题和侧边栏是所有 Visualforce 的标准做法 网站。

用户输入和交互

使用 、 属性和传递 HTML 属性 创建适合移动设备的表单和用户界面,这些表单和用户界面高效且可利用 本机移动浏览器功能。

<apex:input>type

如果没有键盘和鼠标,用户可能很难填写标准 HTML 表单 并在移动设备(尤其是手机)上进行交互。对于 Visualforce 页面,这 不要使用 JavaScript 远程处理来发出请求,请选择 Visualforce 组件 着眼于移动用户的表单输入。您可以对 Visualforce 页面进行的其他更改都不会有 与利用新的 HTML5 和移动浏览器功能相比,对可用性的影响更大 以改进窗体和用户界面控件。

选择高效的输入元素

用于获取用户输入 尽可能。 是一个 HTML5 就绪、适合移动设备的通用输入组件,可适应 表单字段所需的数据。它甚至更灵活,因为它使用该属性允许客户端浏览器 显示适合类型的用户输入小组件,例如日期选择器,或使用 特定于类型的键盘,使在移动设备上输入输入变得更加容易。<apex:input><apex:input><apex:inputField>type

您还可以使用 为与 Salesforce 上的字段对应的值创建 HTML 输入元素 对象。 改编 HTML 生成与基础 sObject 字段的数据类型相对应。通常 这是您想要的,但如果不是,请使用该属性覆盖自动数据 类型检测。但是,请注意,这会生成大量 HTML,并且需要额外的 要加载的资源,这意味着它不是最有效的组件 通过移动无线连接。<apex:inputField><apex:inputField>type<apex:inputField>

使用 type 属性创建 适合移动设备的输入元素

在组件上设置属性,并且 ,如果您使用 IT – 显示特定于数据类型的键盘和其他输入用户界面小部件 在触摸屏上更易于使用。该值将传递到生成的 HTML 元素,用于在 Salesforce 应用程序。type<apex:input><apex:inputField><input>

当用户单步执行表单元素时,该表单元素的输入方法会进行调整 对于预期的数据类型。文本字段显示标准键盘、电子邮件字段 显示带有“@”符号和 分配给键的“.com”,日期字段显示日期选择器,依此类推 上。下面是一个表单示例,说明了这是如何实现的 工程:

<apex:form >
  
    <apex:outputLabel value="Phone" for="phone"/>
    <apex:input id="phone" value="{!fPhone}" type="tel"/><br/>
      
    <apex:outputLabel value="Email" for="email"/>
    <apex:input id="email" value="{!fText}" type="email"/><br/>
      
    <apex:outputLabel value="That Number" for="num"/>
    <apex:input id="num" value="{!fNumber}" type="number"/><br/>
      
    <apex:outputLabel value="The Big Day" for="date"/>
    <apex:input id="date" value="{!fDate}" type="date"/><br/>
      
</apex:form>

如 用户在表单字段中移动,通过点击它们或点击“下一步”按钮,键盘会更改以匹配预期 字段的数据。

这些特定于类型的键盘使使用者更容易填写表单 他们的移动设备。

<apex:input>允许设置以下显式值:

type

  • 日期
  • 日期时间
  • 日期时间-本地
  • 时间
  • 电子邮件
  • 范围
  • 搜索
  • 电话
  • 发短信
  • 网址

您还可以设置为 auto,并且 使用关联的控制器属性或方法的数据类型。

type

HTML 属性,包括新的 HTML5 功能,是 HTML 的标准部分。有关属性的其他详细信息、可以使用它的用途以及用途 与移动开发相关,请参阅 WHATWG 的输入类型属性值和说明列表。 并非所有值都支持 Visualforce 输入 组件。如果要使用 Visualforce 不支持的值,请使用 static HTML 而不是 Visualforce 标记。typetype

使用 HTML5 传递属性进行客户端验证

将您和其他 Visualforce 组件上的直通属性设置为 启用其他 HTML5 功能,例如客户端验证。通过执行基本 验证,可以避免向服务器发送请求,并且 等待响应,当表单上有易于纠正的错误时。<apex:input>传递前缀为 到生成的 HTML,并删除前缀。启用客户端 验证,设置属性 要匹配预期的标记 表单值。这将向 生成的标记,启用 该字段的客户端验证。

html-html-pattern<apex:input>pattern<input>

注意

客户端验证要求 Visualforce 页面 设置为 API 版本 29.0 或更高版本,并将页面设置为 .docTypehtml-5.0验证模式是正则表达式。根据表单输入进行检查 表达式,如果匹配,则认为字段输入有效。如果它 不匹配,则输入被视为无效;错误消息是 ,表单将不会提交到服务器。这是一个 需要来自特定电子邮件地址的字段示例 域:

<apex:input id="email" value="{!fText}" type="email"
    html-placeholder="you@example.com"
    html-pattern="^[a-zA-Z0-9._-]+@example.com$"
    title="Please enter an example.com email address"/>

其他可设置为直通属性的有用 HTML5 属性包括:

  • placeholder(使用属性设置)- 添加 幻影文本添加到字段中,以向用户显示示例输入。html-placeholder
  • title(使用 on 的属性和组件的属性进行设置 without a title attribute) – 添加一条错误消息,以便在以下情况下使用:字段 客户端验证失败。title<apex:input>html-title

有关如何使用属性来增强 HTML 元素可用性的灵感,HTML5 表单简介和新增功能 Attributes 是对 HTML5 中新功能的一个很好的调查。为了进一步 详细信息,尤其是对于移动用户的详细信息,以及客户端表单验证的详细信息, 请参阅客户端表单验证和改善移动设备上的用户体验 WHATWG 的 HTML:生活标准中的设备。<input>

管理导航

Salesforce 移动应用程序使用事件管理导航。导航事件 framework 作为 JavaScript 对象提供,它提供了许多实用程序 使创建“正常工作”的编程导航变得轻而易举的功能。这 优势是更适合移动环境的导航体验。它还使 创建完成后导航,例如在订单完成后重定向到订单页面 成功提交,对 Salesforce 开发人员来说更容易。在 Salesforce 移动应用程序中,Visualforce 页面的程序化导航通常 工作原理如下:

  1. 用户调用 Visualforce 页面,通常从导航菜单或 操作栏中的操作。
  2. Visualforce 页面加载并运行,包括任何自定义控制器或 页面调用的扩展代码。
  3. 用户以某种方式与页面交互:例如,填写一些表单 值。
  4. 用户提交表单,或在页面上执行一些其他操作 提交更改。
  5. 控制器或扩展代码运行,将更改保存到 Salesforce,以及 返回操作的结果。
  6. Visualforce 页面使用 JavaScript 响应处理程序接收结果 操作,成功后,通过将用户重定向到新的 页面,显示其操作的结果。

应用的导航框架可以轻松处理此方案。

另一个常见的用例是简单地将链接或其他用户界面控件添加到 页面,从该 Visualforce 页面移动到应用程序中的另一个页面。此导航 也可以通过应用程序的导航框架轻松管理。

在这些情况下,导航由一个特殊的实用程序 JavaScript 对象 .当出现以下情况时,该对象会自动添加到所有 Visualforce 页面中 它们在 Salesforce 移动应用程序内运行。此对象提供了许多函数 在运行时触发导航事件。若要使用这些函数,可以调用它们 直接从页面的 JavaScript 代码中获取,也可以将调用作为点击处理程序附加到 元素。sforce.onesforce.one下面是一个 JavaScript 函数,用于创建要添加到 Google 的标记 地图。

function setupMarker(){ 

    // Use JavaScript nav function to determine if we are
    // in the Salesforce mobile app and set navigation link appropriately
    var warehouseNavUrl = 
        'sforce.one.navigateToSObject(\'' + warehouse.Id + '\')';

    // Wrap the warehouse details with the link to 
    // navigate to the warehouse details
    var warehouseDetails = 
        '<a href="javascript:' + warehouseNavUrl + '">' + 
        warehouse.Name + '</a><br/>' + 
        warehouse.Street_Address__c + '<br/>' + 
        warehouse.City__c + '<br/>' + 
        warehouse.Phone__c;
   
    // Create a panel that will appear when a marker is clicked
    var infowindow = new google.maps.InfoWindow({ 
        content: warehouseDetails
    });
   
    // ...
}

这 第一行构建一个字符串 ,当用作 JavaScript URL,导航到仓库的详细信息页面。链接已创建 ,并显示在单击标记时显示的信息面板(放在字符串中)。 单击仓库名称将带您进入该仓库的详细信息页面(省略 函数代码的一部分涉及 Google Maps API 调用以创建标记和 将其添加到地图中)。

warehouseNavUrlwarehouseDetails如果您有在 Salesforce 移动应用程序中运行的 JavaScript 代码或 HTML 标记, 请记住以下注意事项:

  • 不要使用 直接操作浏览器 URL。这与应用程序的 导航管理系统。window.location.href
  • 不要在导航 URL 中使用; 您无法在应用程序内打开新窗口。target=”_blank”

Canvas 框架中的导航方法

如果您使用的是 Canvas,则有一种更简单的方法来控制 Canvas 周围的导航 Salesforce 移动应用程序中的应用程序和画布个人应用程序。

您可以使用 Lightning Platform 方法控制应用程序中的导航。Canvas 框架中的这些方法是 驻留在 JavaScript 库中的事件。调用导航方法之一时 从画布代码中,您将一个事件发送到 Salesforce,该事件读取有效负载并指示 用户到指定目标。

将导航方法引用为事件变量,并使用 名称和有效负载。例如:

var event = {name:”s1.createRecord”, payload: {entityName: “Account”, recordTypeId: “00h300000001234”}};

有关使用新方法的更多信息,请参阅用于 Canvas 的 Salesforce 移动应用程序导航方法 Canvas 开发人员指南中的应用。

  • 使用 sforce.one 对象
    进行导航和消息传递 Salesforce Platform 包括用于导航和消息传递的事件机制。这在 Visualforce 中显示为名为 的 JavaScript 对象。它可以在 Salesforce 移动应用程序中显示的任何页面中使用。sforce.one
  • sforce.one 如何处理 API 版本 该对象在新版本
    中经常得到改进。为了保持向后兼容性,提供了特定于版本的行为,你可以在应用中使用特定版本的 。sforce.onesforce.onesforce.one

使用 sforce.one 对象进行导航和消息传递

Salesforce Platform 包括用于导航和消息传递的事件机制。这 在 Visualforce 中显示为名为 的 JavaScript 对象。它可在 Salesforce 移动版中显示的任何页面中使用 应用程序。

sforce.one

该对象提供以下功能 功能。使用对象中的点分表示法引用函数。例如:。sforce.onesforce.onesforce.one.navigateToSObject(recordId, view)

有关这些函数触发的基础事件的更多详细信息,请参阅Lightning Aura组件开发人员指南。

功能描述
back(​[refresh])导航到历史记录中保存的上一个状态。这相当于单击一个 浏览器的“后退”按钮。sforce.one刷新是可选的。默认情况下, 页面不刷新。通过刷新 页面(如果可能)。true
navigateToSObject(​recordId​[, view])导航到 sObject 记录, 由 recordId 指定。这个记录“home”有几个视图, 在 Salesforce 移动应用程序中以幻灯片形式提供,用户可以滑动 之间。view 是可选的,默认为 。视图指定幻灯片 在记录主页中最初显示。detail注意对应的记录 ID 不支持 ContentNote SObjects。可能的值如下所示。detail:记录详细信息幻灯片chatter:Chatter 幻灯片related:相关幻灯片的视图
navigateToURL(​url​[, isredirect])导航到指定的 URL。支持相对根 URL 和绝对 URL。相对 URL 是 相对于闪电网域根目录,并保留导航历史。例如 Visualforce 页面的相对根 URL 以正斜杠为前缀,例如 .支持或不支持的相对 URL。外部 URL(即 Lightning 域之外的 URL)在单独的浏览器中打开 窗。/apex/c__Listen../apex/c__Listenapex/c__Listen注意根据 用户的设备平台、设备设置、Salesforce 版本,以及 要打开的外部 URL 的身份验证要求,单独的 浏览器窗口可能需要身份验证或 重新身份验证。使用相对 URL 导航到 应用内的不同屏幕。使用外部 URL 允许用户访问 不同的网站或应用,他们可以在其中执行不需要保留的操作 在您的应用中。若要返回到应用,请返回由外部打开的单独窗口 当用户使用完其他应用时,必须关闭 URL。新窗口有 与应用不同的历史记录,当窗口 闭。这也意味着用户无法单击“后退”按钮返回到 应用程序;用户必须关闭新窗口。mailto:支持 、 、 和其他 URL 方案 启动外部应用程序并尝试“做正确的事”。但是,支持各不相同 通过移动平台和设备。 并且是可靠的,但我们建议您 在预期范围内测试任何其他 URL 设备。tel:geo:mailto:tel:isRedirect 是可选的,默认为 。将其设置为指示新 URL 应替换 导航历史记录。falsetrue当您从模式导航到 URL 时,例如从 为快速操作启用的组件,模态不会由 违约。要在导航时自动关闭模式,请设置为 。isredirecttrue注意在 or any 的处理程序中使用时要小心。即使 ,命令按钮的默认单击操作是 表单发布。在此方案中,命令按钮执行窗体发布和操作,要求用户 单击“后退”按钮两次以导航到上一页。为了防止 默认的单击操作,将处理程序配置为调用或返回 。navigateToURLonClick<apex:commandButton><button type=”submit”><input type=”submit”>isredirect=truenavigateToURLonClickevent.preventDefault()false注意与 ContentNote SObjects 对应的 URL 不是 支持。
navigateToFeed(​subjectId, type)导航到 指定的类型,范围限定为 subjectId。为 某些 Feed 类型,则 subjectId 是必需的 但被忽略了。对于这些 Feed 类型,请将当前用户的 ID 作为 subjectId。type 是源类型。这 可能的值如下所示。BOOKMARKS:包含保存为书签的所有提要项 由上下文用户提供。传递当前用户的 ID 作为 subjectId。COMPANY:包含除 类型。查看源 项,则用户必须具有对其父级的共享访问权限。 传递当前用户的 ID 作为 subjectId。TrackedChangeFILES:包含包含文件的所有源项 由上下文用户关注的人员或组发布。 传递当前用户的 ID 作为 subjectId。GROUPS:包含所有组中的所有源项 上下文用户拥有或属于其成员。 传递当前用户的 ID 作为 subjectId。NEWS:包含上下文用户关注的人员、用户所属组的所有更新 用户关注的成员,以及用户正在关注的归档和记录。包含所有更新 对于其父级为上下文用户的记录。 传递当前用户的 ID 作为 subjectId。PEOPLE:包含所有人发布的所有提要项 上下文用户跟随。 传递当前用户的 ID 作为 subjectId。RECORD:包含其父项为 指定的记录,可以是组、用户、对象、文件或任何其他 标准或自定义对象。当记录为组时,源还包含 提及该组的 Feed 项目。当记录是用户时,源 仅包含该用户的源项。您可以获取其他用户的记录 饲料。将记录的 ID 作为 subjectId 传递。TO:包含提及上下文用户的所有源项。包含饲料 上下文用户评论的项目和上下文用户创建的源项目 被评论。 传递当前用户的 ID 作为 subjectId。TOPICS:包含包含 指定的主题。将主题的 ID 作为 subjectId 传递。此值为 仅在 Salesforce 移动 Web 版中受支持。主题在 适用于 iOS 的 Salesforce 或适用于 Android 的 Salesforce。
navigateToFeedItemDetail(​feedItemId)导航到特定源 item、feedItemId 和任何关联的注释。
navigateToRelatedList(​relatedListId, parentRecordId)导航到相关列表 parentRecordId。例如,要显示 Warehouse 对象,parentRecordId 为 。Warehouse__c.IdrelatedListId 是要显示的相关列表的 API 名称或 ID。
navigateToList(​listViewId​, listViewName, scope)导航到以下列表视图 由 listViewId 指定,listViewId 是列表视图的 ID 显示。listViewName 设置列表视图的标题。它 不需要与为列表视图保存的实际名称匹配。要使用 保存名称,将 listViewName 设置为 null。将 scope 设置为视图中 sObject 的名称,例如, “帐户”或“MyObject__c”。
createRecord(​entityName​[, recordTypeId][, defaultFieldValues])打开页面以创建记录 对于指定的 entityName,例如,“Account”或 “MyObject__c”。recordTypeId 是可选的,并指定 所创建对象的记录类型。在不提供 recordTypeId 的情况下调用 createRecord 可能会导致 错误。defaultFieldValues 是可选的,如果提供, 在记录创建面板上预填充字段,包括未显示在 面板。用户必须对具有预填充值的字段具有创建访问权限。 保存期间由字段访问限制导致的错误不显示错误 消息。
editRecord(​recordId)打开页面以编辑记录 由 recordId 指定。
showToast({toastParams})显示 Toast。Toast 显示一条消息 在视图顶部的标题下方。该对象设置 Toast 的属性。使用任何属性 可用于 Aura 活动。为 例:toastParamsforce:showToastsforce.one.showToast({ "title": "Success!", "message": "The record was updated successfully." });
publish(​messageChannel,​message)使用 闪电消息服务。请参阅在消息通道上发布。
subscribe(​messageChannel,​function)使用 Lightning 消息服务订阅 messageChannel。当订阅上的消息时,提供的功能运行 消息通道已发布。该函数返回一个可与 一起使用的订阅对象。请参阅订阅和 取消订阅消息频道。subscribe()unsubscribe()
unsubscribe(​subscription)从消息通道中取消订阅对象的订阅。请参阅订阅和 取消订阅消息频道。

使用对象时,请记住以下几点:

sforce.one

  • 调用 可能会导致 如果 URL 引用了对象或 Chatter 的标准页面,则出现“不支持的页面”错误 页面。为避免此错误,请确保 URL 以正斜杠开头 (/_ui 而不是 _ui)。sforce.one.navigateToURL
  • 该方法不 尊重 Visualforce 覆盖标准操作。sforce.one.createRecord
  • 开发人员可以使用该类来 控制 Salesforce 移动应用程序的导航。某些操作及其关联的 URL 尚不完全受支持。 例如,使用操作 克隆或编辑可能无法按预期工作。计划在将来的版本中提供全面支持。pageReferencepageReferencestandard_recordPage

sforce.one 如何处理 API 版本

对象经常改进 在新版本中。为了保持向后兼容性,提供了特定于版本的行为,您可以使用特定的 版本。

sforce.onesforce.onesforce.one

默认情况下,使用与 请求的 Visualforce 页面的 API 版本。例如,如果 Visualforce 页面 API 版本为 30.0,该页面上默认使用的 JavaScript 使用 API 版本 30.0 的 。sforce.onesforce.onesforce.one

这意味着,当 Visualforce 页面更新到新的 API 版本时,该页面 自动使用 的更新版本。在前面的示例中,如果该 Visualforce 页面已更新 到 API 版本 31.0,则使用 API 版本 31.0 的应用功能。sforce.onesforce.onesforce.one如果新 API 版本中的更新行为导致页面功能出现兼容性问题,则 有三个选项来纠正问题。

sforce.one

  • 将 Visualforce 页面的 API 版本恢复到以前的版本。此操作 无需更改代码。
  • 更新页面功能的代码以解决问题。此解决方案是 最好,但它可能需要一些调试,并且肯定需要代码 变化。
  • 使用特定版本的 。 此解决方案通常需要最少的代码更改。sforce.one

注意

sforce.one在 14 年冬季添加 (API 版本 29.0),直到 14 年夏季(API 版本 31.0)才进行版本控制。版本 31.0 之前的所有版本都是 与版本 31.0 相同。您可以为对 Visualforce 有效的任何版本指定一个版本,即从 版本 15.0 设置为当前 API 版本。sforce.onesforce.one

使用特定版本的 sforce.one

要使用特定版本的 ,请使用 函数和 为其提供 API 版本和需要使用特定 的版本。适当的 的版本是自动的 由此调用加载。sforce.onesforce.one.getVersion()sforce.onesforce.one签名为:

sforce.one.getVersion()

sforce.one.getVersion(versionString, callbackFunction);

versionString 是应用程序所需的 API 版本。 它始终是两位数、句点和一位数字,例如“30.0”。无效的调用 版本字符串以静默方式失败。

callbackFunction 是一个 JavaScript 函数,它使用特定的 的版本。 经营 异步,回调函数在完成加载 请求的 版本。你 callback 函数接收单个参数,即指定 API 版本的对象。使用传递的对象 在而不是全局制作 对符合 API 的调用 应用所需的版本。sforce.onesforce.one.getVersion()sforce.onesforce.onesforce.onesforce.one

使用特定版本的 sforce.one 的示例

接下来的示例都将 Create Account 函数添加到以下输入中 按钮:

<input type="button" value="Create Account" onclick="btnCreateAccount()" id="btnCreateAcct"/>

默认为 Visualforce 页面的 API 版本应使用默认版本的应用代码 – 与 Visualforce 页面的 API 相对应的版本 版本 – 不需要请求版本。使用该版本会自动发生, 代码是 简单。

sforce.one

<script>
    function MyApp() {
        this.createAccount = function() {
            sforce.one.navigateToURL("/001/e");
        };
    } 

    var app = new MyApp();

    function btnCreateAccount() {
        app.createAccount();
    }
</script>

应用功能是在对象中创建的,然后事件处理函数在该事件 发生按钮咔嗒声。将应用程序功能与应用程序事件分离 处理是最佳做法,它为您设置了使用特定于版本的版本 之。MyAppsforce.one

使用特定的 sforce.one API 版本 (简单)要使用特定版本的 ,请获取 并保存对对象的版本化实例的引用。然后使用此对象可以 拨打电话。最简单的方法是 将其保存在对象中。在下一个 示例中,对 的版本化实例的引用位于 大胆。

sforce.onesforce.oneMyAppsforce.one

<script>
    function MyApp(sfone) {
        this.createAccount = function() {
            sfone.navigateToURL("/001/e");
        };
    } 
        
    var app30 = null;

    function btnCreateAccount() {
        // Create our app object if not already defined
        if(!app30) {
            // Create app object with versioned sforce.one
            sforce.one.getVersion("30.0", function(sfoneV30) {
                app30 = new MyApp(sfoneV30);
                app30.createAccount();
            });
            return;
        }
        app30.createAccount();        
    }
</script>

在前面的示例中,事件处理函数是从第一个扩展而来的 示例,以包括创建特定于版本的 实例。如果您的应用需要混合多个 versions,您可以创建多个具有适当版本和名称的实例。不过,不止一两个是 管理起来很麻烦。我们建议改用下一种方法。sforce.oneMyApp

使用特定的 sforce.one API 版本 (最佳)组织应用代码的更好方法是在应用初始化中创建特定于版本的实例 代码块,以便您可以保留事件处理 分开。

sforce.one

<script>
    function MyApp(sfone) {
        this.createAccount = function() {
            sfone.navigateToURL("/001/e");
        };
    } 
        
    var app30 = null;

    // Initialize app: get versioned API, wire up clicks
    sforce.one.getVersion("30.0", function(sfoneV30) {
        // Create app object with versioned sforce.one
        app30 = new MyApp(sfoneV30);

        // Wire up button event
        var btn = document.getElementById("btnCreateAcct");
        btn.onclick = btnCreateAccount;
    });

    // Events handling functions
    // Can't be fired until app is defined
    function btnCreateAccount() {
        app30.createAccount();
    }
</script>

在此示例中,应用初始化仅由空格和注释分隔。 但是你可以把它分成几个函数,以便更好地封装。

使用特定的 sforce.one API 版本 (同步)您可以通过在页面上手动包含特定版本的 JavaScript 来触发同步模式。这 库 URL 的格式 是:/sforce/one/sforceOneVersion/api.js。 下面是一个示例:

sforce.onesforce.one

<script src="/sforce/one/30.0/api.js"></script>
<script>
    function MyApp(sfone) {
        this.createAccount = function() {
            sfone.navigateToURL("/001/e");
        };
    } 
        
    var app = null;

    sforce.one.getVersion("30.0", function(sfoneV30) {
        app = new MyApp(sfoneV30);
    });

    // Events handling function
    // Can't be fired until app is defined
    function btnCreateAccount() {
        app.createAccount();
    }
</script>

虽然有些情况需要同步模式,但异步版本是 首选。如果您忘记手动包含正确版本的库,您的代码将包含错误 难以诊断。sforce.one

Salesforce Lightning Design System 简介

Salesforce Lightning Design System (SLDS) 可帮助您构建具有外观的应用程序 和 Lightning Experience 的感觉,无需编写任何一行 CSS。SLDS 是一个 CSS 框架 这使您可以访问我们的开发人员用于创建的图标、调色板和字体 闪电体验。

Lightning Experience UI 核心原则

SLDS 所代表的 Lightning Experience UI 采用四核设计精心打造 原则。我们鼓励您在开发应用程序时牢记这些内容。

  • 清晰度 — 消除歧义。使人们能够看到、理解和行动 信心。
  • 效率 — 简化和优化工作流程。智能预测需求 帮助人们更好、更智能、更快速地工作。
  • 一致性 — 通过应用相同的方法创造熟悉感并加强直觉 解决同一问题。
  • 美丽 — 通过深思熟虑和 优雅的工艺。

SLDS 的优势

SLDS 为您提供了创建符合原则、设计语言和 Lightning Experience 的最佳实践。以下是使 SLDS 如此有用的优点:

  • 在扩展现有功能时,它提供了统一的体验和简化的工作流程 或与外部系统集成。
  • 它不会过度强制执行默认值,例如填充和边距。
  • 它会不断更新。只要您使用的是最新版本的 SLDS,您的页面 与 Lightning Experience 一致。
  • 它包括 CSS 框架中的可访问性。
  • 它适用于其他 CSS 框架,如 Bootstrap。
  • 将 SLDS 应用于 Visualforce 页面 您可以使用 Lightning 设计系统 (SLDS) 构建与 Salesforce 移动应用程序的外观相匹配的 Visualforce 页面
    。要使用 SLDS,需要对代码进行一些调整,并需要记住一些事项。在大多数情况下,使用 SLDS 的 Visualforce 代码可以正常工作。
  • 在 Visualforce
    中使用 SLDS 图标 Lightning 设计系统 (SLDS) 包括 PNG 和 SVG(包括个人和 spritemap)版本的动作、自定义、文档类型、标准和实用程序图标。
  • 使用 SLDS 为 Salesforce 移动应用程序创建 Visualforce 页面 让我们创建一个 Visualforce 页面,该页面显示您最近访问的帐户,并使用 Lightning 设计系统 (SLDS) 进行样式设置,并将其添加到移动导航菜单中。
  • 使用 SLDS
    的响应式页面设计 响应式设计是一种网页设计方法,旨在创建在线用户界面,在各种屏幕尺寸上提供最佳的查看体验,包括轻松阅读和导航。

将 SLDS 应用于 Visualforce 页面

您可以使用 Lightning 设计系统 (SLDS) 构建与 Salesforce 移动应用程序的外观。要使用 SLDS,需要对代码进行一些调整,然后 要记住的事情很少。在大多数情况下,使用 SLDS 的 Visualforce 代码无需 问题。

在 Visualforce Pages 中使用 SLDS

每次使用 SLDS 时,请添加到 页面并将代码包装在范围类中。<apex:slds /><div class=”slds-scope”>…</div>

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

  <!-- Import the Design System style sheet -->
  <apex:slds />

    <!-- REQUIRED SLDS WRAPPER -->
    <div class="slds-scope">

我们讨论的 Visualforce 移动开发中的许多最佳实践都适用于此处 也。Apex 标记,例如 和 尚不支持使用 使用 SLDS。<apex:pageblock><apex:inputField>

SLDS 类命名

SLDS 使用称为 Block-Element-Modifier 语法 (BEM) 的标准类命名约定来 使类名不那么模棱两可。

  • 块表示高级组件(例如,)。car
  • 元素表示组件 () 的后代。car__door
  • 修饰符表示块或元素的特定状态或变体 ()。car__door–red

在 Visualforce 中使用 SLDS 图标

闪电设计系统 (SLDS) 包括 PNG 和 SVG(包括个人和 spritemap) 我们的 action、custom、doctype、standard 和 utility 图标的版本。

要在 Visualforce 页面中使用 SVG 精灵图图标,请将属性添加到标签中。xmlns=”http://www.w3.org/2000/svg” xmlns:xlink=”http://www.w3.org/1999/xlink”<html>

<span class="slds-icon_container slds-icon-standard-account" title="description of icon when needed">
 
  <svg aria-hidden="true" class="slds-icon">
 
    <use xlink:href="{!URLFOR($Asset.SLDS, 'assets/icons/standard-sprite/svg/symbols.svg#account')}"></use>
  </svg>
 
   <span class="slds-assistive-text">Icon Assistive Text</span>

</span>

由于图标是独立的并且具有含义,因此我们将其放置在带有 .slds-icon_container class

图标没有开箱即用的背景颜色。要设置背景颜色,我们应用第二个 类到跨度。要对特定图标使用默认颜色,请构造 图标的特定实用程序类,通过连接 、 Sprite 映射名称和 . 将该类应用于元素。在示例中 我们使用“标准”精灵映射和“帐户”图标,因此该类是 .slds-icon--icon<span>slds-icon-standard-account

在 中,我们有一个带有类的元素。元素反过来 包含一个 <use> 标记,该标记根据图标的属性指定要显示的图标。<span><svg>slds-icon<svg>xlink:href

要设置 xlink:href 路径:

  1. 从图标页面中选择要使用的图标。记下它属于哪个类别 (操作、自定义、文档类型、标准或实用程序)。
  2. 通过连接类别 sprite 来完成 xlink:href 属性 (例如,“standard-sprite”)、/svg/symbols.svg# 和特定图标 在其中(例如,“帐户”)。这为我们提供了路径 assets/icons/standard-sprite/svg/symbols.svg#account。

在标记后,辅助文本位于 span 与类。<svg>slds-assistive-text

使用 Salesforce 移动应用程序创建 Visualforce 页面 SLDS系列

让我们创建一个 Visualforce 页面,该页面显示您最近访问的帐户,并且是 使用闪电设计系统(SLDS)进行样式设计,并将其添加到移动导航中 菜单。

  1. 首先,让我们创建 Visualforce 页面。
  2. 打开开发者控制台,点击“文件”|”新品 |Visualforce 页面。输入 SLDSPage 作为页面名称。
  3. 在编辑器中,将任何标记替换为以下内容。<apex:page showHeader="false" standardStylesheets="false" sidebar="false" applyHtmlTag="false" applyBodyTag="false" docType="html-5.0"> <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="x-ua-compatible" content="ie=edge" /> <title>SLDS LatestAccounts Visualforce Page in Salesforce Mobile</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <!-- Import the Design System style sheet --> <apex:slds /> </head> <apex:remoteObjects > <apex:remoteObjectModel name="Account" fields="Id,Name,LastModifiedDate"/> </apex:remoteObjects> <body> <!-- REQUIRED SLDS WRAPPER --> <div class="slds-scope"> <!-- PRIMARY CONTENT WRAPPER --> <div class="myapp"> <!-- ACCOUNT LIST TABLE --> <div id="account-list" class="slds-p-vertical--medium"></div> <!-- / ACCOUNT LIST TABLE --> </div> <!-- / PRIMARY CONTENT WRAPPER --> </div> <!-- / REQUIRED SLDS WRAPPER --> <!-- JAVASCRIPT --> <script> (function() { var outputDiv = document.getElementById('account-list'); var account = new SObjectModel.Account(); var updateOutputDiv = function() { account.retrieve( { orderby: [{ LastModifiedDate: 'DESC' }], limit: 10 }, function(error, records) { if (error) { alert(error.message); } else { // create data table var dataTable = document.createElement('table'); dataTable.className = 'slds-table slds-table--bordered slds-text-heading_small'; // add header row var tableHeader = dataTable.createTHead(); var tableHeaderRow = tableHeader.insertRow(); var tableHeaderRowCell1 = tableHeaderRow.insertCell(0); tableHeaderRowCell1.appendChild(document.createTextNode('Latest Accounts')); tableHeaderRowCell1.setAttribute('scope', 'col'); tableHeaderRowCell1.setAttribute('class', 'slds-text-heading_medium'); // build table body var tableBody = dataTable.appendChild(document.createElement('tbody')) var dataRow, dataRowCell1, recordName, data_id; records.forEach(function(record) { dataRow = tableBody.insertRow(); dataRowCell1 = dataRow.insertCell(0); recordName = document.createTextNode(record.get('Name')); dataRowCell1.appendChild(recordName); }); if (outputDiv.firstChild) { // replace table if it already exists // see later in tutorial outputDiv.replaceChild(dataTable, outputDiv.firstChild); } else { outputDiv.appendChild(dataTable); } } } ); } updateOutputDiv(); })(); </script> <!-- / JAVASCRIPT --> </body> </html> </apex:page>
    • 标签允许 访问 SLDS 样式表。该组件是 将 SLDS 作为静态资源上传并在 Visualforce 中使用它 页面。<apex:slds />
    • 包装器对于任何 SLDS 样式的内容都是必需的。仅限 SLDS 样式 应用于其中包含的元素。<div class=”slds-scope”>
  4. 此页面也适合移动设备使用。让我们将页面添加到 Salesforce 移动菜单。
  5. 为移动应用启用页面。
    1. 在“设置”中,在“快速”中输入 Visualforce 页面 “查找”框,然后选择“Visualforce 页面”。
    2. 单击列表中 SLDSPage Visualforce 页面旁边的编辑
    3. 选择可用于 Lightning Experience、Experience 构建器网站和移动应用程序
    4. 点击保存
  6. 为 Visualforce 页面创建一个选项卡。
    1. 在“设置”中,在“快速查找”框中输入“选项卡”, ,然后选择选项卡
    2. 在“Visualforce 选项卡”部分中,单击“新建”。
    3. 在“Visualforce 页面”下拉列表中,选择“SLDSPage”。
    4. 在选项卡标签字段中,输入 SLDS 页面。请注意,“选项卡名称”字段是自动填充的
    5. 单击“选项卡样式”字段,然后选择“菱形”样式。此样式的图标显示为 Salesforce 移动导航菜单。
    6. 单击“下一步”,然后单击“下一步”, 然后保存
  7. 将选项卡添加到移动导航菜单。
    1. 在“设置”中,在“快速查找”中输入“移动应用” 框中,然后选择 Salesforce 导航
    2. 选择“SLDS 页面”选项卡,然后单击“添加”。SLDS 项将添加到“已选择”(Selected) 的底部 列表。
    3. 点击保存

使用 SLDS 的响应式页面设计

响应式设计是一种网页设计方法,旨在创建在线用户界面 在各种屏幕上提供最佳的观看体验,包括轻松阅读和导航 大小。

响应式用户界面通过使用流畅的、 基于比例的网格、灵活的图像和 CSS3 媒体查询。使用响应式设计,您可以 可以创建看起来很棒且在手机和平板电脑上运行良好的 Visualforce 页面。

标准 Salesforce 应用程序页面使用响应式设计来提供设备优化的布局。这 主要技术是电话的堆叠单列布局,以及并排的两列布局 平板电脑的布局。该页面对于所有设备都是相同的,并适应其屏幕尺寸 显示上。

SLDS电网系统

闪电设计系统 (SLDS) 使用基于 Flexbox 的网格来提供灵活的、 移动优先、与设备无关的脚手架系统。网格系统可让您划分页面 分成行和列,并为不同尺寸的屏幕定义布局变化。网格可以是 嵌套以创建复杂的布局。

网格系统由两部分组成,网格包装器(类)和其中的列(类)。默认情况下,列的大小相对于其内容。slds-gridslds-col

您还可以使用 SLDS 中的大小调整帮助程序手动指定列大小。它们使用一种格式,其中 X 表示分数 总空间 Y。例如,表示为可用空间的 50% 的宽度。使用手动调整大小类 帮助程序,您可以在以下网格中指定列比 – 2、3、4、5、6 和 12.slds-size–X-of-Yslds-size–1-of-2

使用 SLDS 创建响应式设计页面

  1. 打开开发者控制台,点击“文件”|”新品 |Visualforce 页面。输入页面名称。SLDSResponsivePage
  2. 在编辑器中,将任何标记替换为 以后。<apex:page showHeader="false" standardStylesheets="false" sidebar="false" applyHtmlTag="false" applyBodyTag="false" docType="html-5.0"> <html xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" lang="en"> <head> <meta charset="utf-8" /> <meta http-equiv="x-ua-compatible" content="ie=edge" /> <title>SLDS ResponsiveDesign Visualforce Page in Salesforce Mobile</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <!-- Import the Design System style sheet --> <apex:slds /> </head> <body> <!-- REQUIRED SLDS WRAPPER --> <div class="slds-scope"> <!-- PRIMARY CONTENT WRAPPER --> <!-- RESPONSIVE GRID EXAMPLE --> <div class="myapp"> <div class="slds-grid slds-wrap"> <div class="slds-col slds-size--1-of-1 slds-small-size--1-of-2 slds-medium-size--1-of-4"> <div class="slds-box slds-box_x-small slds-text-align_center slds-m-around--x-small">Box 1</div> </div> <div class="slds-col slds-size--1-of-1 slds-small-size--1-of-2 slds-medium-size--3-of-4"> <div class="slds-box slds-box_x-small slds-text-align_center slds-m-around--x-small">Box 2</div> </div> </div> </div> <!-- / RESPONSIVE GRID EXAMPLE --> </div> </body> </html> </apex:page>这 代码创建一个两列网格,其中两列分别为:
    • 移动屏幕上的全宽和垂直
    • 大小为 1:1,在小屏幕上并排显示(超过 480 像素)
    • 大小为 3:1,在更大的屏幕上并排显示(超过 768 像素)

在桌面和移动设备上查看此页面,了解响应式设计的实际效果。

使用 Visualforce 页面作为自定义操作

如果您的 Visualforce 页面用作自定义操作,请将其设计为可执行操作 根据标准控制者提供的单个记录,或找到记录并对其采取行动,或 记录检索到的自定义控制器代码。

对对象的自定义操作

添加为自定义的 Visualforce 页面 在对象类型的记录的上下文中调用对对象的操作。这 自定义操作将传递一个特定的记录 ID,即用户正在查看的记录 当用户单击自定义操作时。设计页面以对该特定记录执行操作 类型。

用作对象自定义操作的 Visualforce 页面必须使用标准 该对象的控制器。使用控制器 用于添加自定义代码的扩展,包括可以使用 JavaScript 调用的方法 远程处理。@RemoteAction

您的自定义代码可以做的不仅仅是对 原始记录。例如,“创建快速订单”自定义操作 搜索匹配的商品。然后,它会创建发票和明细项,所有 作为为部件创建订单的一部分。该逻辑发生在 原始客户记录 – 发票与客户记录相关 调用快速订单操作的位置。

当您重定向到内部 URL 时 对于您的组织,操作对话框将在完成后关闭或以编程方式关闭 导航离开。如果将重定向设置为指向外部 URL,则 由于外部 URL 在新浏览器中打开,因此行为可能会有所不同 标签。

自定义全局操作

用作全局的 Visualforce 页面 操作可以在许多不同的位置调用,并且没有特定的记录 与他们相关。他们有完全的行动自由,这意味着这取决于你 来编写代码。

更具体地说,用作全局操作的 Visualforce 页面不能使用任何标准控制器。您必须编写一个自定义控制器来处理该页面。你 代码可能会创建一条或多条记录、修改找到的记录等。

当全局操作时 完成后,用户将被重定向到作为 该动作或返回到他们开始的地方。

Visualforce 页面的性能调整

性能是移动 Visualforce 页面的一个重要方面。Visualforce 有一个 缓存机制,帮助您调整页面的性能。

若要为页面启用缓存,请使用以下语句:

<apex:page cache="true" expires="600">

页面缓存的参数包括:

属性描述
缓存指定浏览器是否应缓存页面的布尔值。如果不是 指定,缺省为 .false
到期指定缓存周期(以秒为单位)的整数值。

有关更多信息,请参阅 Developerforce 上的 Force.com 站点最佳实践

更多资源

以下是一些可帮助您调整 Salesforce 应用程序性能的更多资源:

  • 深入了解 Force.com Query Optimizer(网络研讨会)
  • 最大限度地提高 Force.com SOQL、报告和列表视图的性能(博客文章)
  • Force.com SOQL 最佳实践:空值和公式字段(博客 帖子)

将 Visualforce 添加到 Salesforce AppExchange 应用程序

您可以在自己的应用程序中包含 Visualforce 页面、组件或自定义控制器 为 AppExchange 创建。

与 Apex 类不同,托管包中 Visualforce 页面的内容不是 安装包时隐藏。但是,自定义控制器、控制器扩展和 自定义组件是隐藏的。此外,可以使用该属性将自定义组件限制为仅在命名空间中运行。access

Salesforce 建议您仅使用托管软件包来分发任何 Visualforce 或 Apex 组件。之所以提出此建议,是因为托管包接收一个唯一的命名空间,该命名空间是 自动附加到页面、组件、类、方法、变量、 等等。此命名空间前缀有助于防止安装程序的 组织。使用 Visualforce 页面创建包时,应考虑以下注意事项:

  • 如果组件上的属性是 包含在托管包中设置为 ,是 请注意以下限制:accessglobal
    • 组件上的属性不能是 更改为 。accesspublic
    • 所有必需的子组件 (将 required 属性设置为 true 的属性)必须将属性设置为 global。<apex:attribute>access
    • 如果在必需的子项上设置了该属性,则无法删除该属性,或者 改变。default<apex:attribute>
    • 您无法添加新的必需子组件。<apex:attribute>
    • 如果子组件上的属性设置为 ,则无法将其更改为 。access<apex:attribute>globalpublic
    • 如果子组件上的属性设置为 ,则无法更改该属性。access<apex:attribute>globaltype
  • 安装具有非全局组件的包时,在 安装程序:请参阅“组件不是全局的”,而不是组件的内容。在 此外,该元件不包括在元件引用中。
  • 如果为正在安装软件包的组织启用了高级货币管理, 使用和不能使用的 Visualforce 页面 安装。<apex:inputField><apex:outputField>
  • 作为 Salesforce AppExchange 应用程序的一部分包含的任何 Apex 都必须至少具有 75% 累积测试覆盖率。当您将软件包上传到 AppExchange 时,将运行所有测试 以确保它们运行没有错误。当包 安装。
  • 从版本 16.0 开始,如果您将托管 Apex 类用作 Visualforce 控制器, 此外,还需要将以下方法和属性的访问级别设置为“访问级别”,以供订阅者使用 他们:globalglobal
    • 自定义控制器的构造函数
    • Getter 和 setter 方法,包括用于输入和输出组件的方法
    • 获取和设置属性的特性

提示

如果自定义标签有翻译,请包括 通过显式打包所需的语言,在包中进行翻译。

当包含 Visualforce 页面的软件包安装到 组织,则页面从 vf.force.com、visual.force.com 或 visualforce.com 域提供 而不是 salesforce.com 域。这是为了防止恶意代码 在包中,以免影响您的数据。

管理 Visualforce 页面和组件的软件包版本设置

如果 Visualforce 标记引用已安装的托管软件包,则每个软件包的版本设置 保存 Visualforce 标记引用的托管包以帮助向后兼容。 这可确保随着托管包中的组件在后续包版本中的发展,一个 页面仍绑定到具有特定已知行为的版本。

包版本是一个数字,用于标识包中上载的组件集。这 版本号的格式为 (对于 例如,2.1.3)。在每个主要数字中,主要数字和次要数字增加到选定的值 释放。仅针对补丁版本生成和更新。 发布者可以使用包版本来正常发展其托管包中的元素 通过发布后续软件包版本,而不破坏现有的客户集成,使用 包。majorNumber.minorNumber.patchNumberpatchNumber配置 Visualforce 的包版本设置 页面或自定义组件:

  1. 编辑 Visualforce 页面或组件,然后单击版本 设置
  2. 为 Visualforce 页面或组件。此版本的托管包将继续 如果托管包的更高版本是 已安装,除非您手动更新版本设置。若要将已安装的托管包添加到设置列表,请选择一个包 从可用软件包列表中。仅当有 尚未与 页面或组件。
  3. 点击保存

使用包版本设置时,请注意以下事项:

  • 如果保存引用托管的 Visualforce 页面或自定义组件 包,而不指定托管包的版本,页面或 组件与最新安装的托管软件包版本相关联 默认情况下。
  • 您无法移除 Visualforce 页面,或者 托管包的组件版本设置(如果该包是 由页面或组件引用。使用显示 用于查找托管包位置的依赖项 引用。
  • 包订阅者可以使用包版本来引用已删除的组件。 包中的 Visualforce 页面始终使用其包的最新 API 版本。他们无法访问已删除的组件。

不同软件包中 Visualforce 页面的访问控制器

要从不同软件包中的 Visualforce 页面访问 Apex 控制器,请执行以下操作: 在 自定义控制器类。在第一代封装中,您只能开发一个托管 具有给定命名空间的包。在第二代封装中,您可以开发超过 一个具有相同命名空间的托管(或已解锁)包。默认情况下,Visualforce 页面 安装在包中的包无法从另一个包中的 Apex 类调用公共 Apex 方法 包。即使两个包位于同一命名空间中,也是如此。

@namespaceAccessible

下面是如何在 Apex 代码中包含注释的示例。@namespaceAccessible

@namespaceAccessible
public virtual class NsController {
    private String message;
    @namespaceAccessible
    public NsController() {
        this.message = 'default'; // init to non-blank value
    }
    @namespaceAccessible
    public virtual String getMessage() {
       return this.message;
    }
    @namespaceAccessible
    public virtual void setMessage(String msg) {
        this.message = msg;
    }
}

首先,在控制器上方添加注释,使其从 命名空间。您必须对控制器进行注释,以便任何方法 您添加到注释中也是可见的。然后,对于您希望可见的每个方法 在命名空间中,在方法之前添加注释。仅使用注释 对于您希望在包外部可见但在同一包内的方法 命名空间。@namespaceAccessible