在Visualforce页面中使用Visual Flow
在本文中,我们将通过一个示例说明如何将“流”(Visual Flow)用于Visualforce页面。
更全面的知识可以参考官方文档。
创建流
我们要创建一个流,它的作用是得到一个“客户”(Account)变量,然后根据其中的自定义字段“是否破产”(Bankrupt__c)来决定是否在客户名称后面加上“已破产”的字样。
步骤如下:
- 在新的流中创建一个“SObject对象变量”,这个变量会用于存储“客户”对象的信息

- 创建一个“决策”元素,在其中检查刚才建立的客户变量的“是否破产”字段值

- 创建一个“分配”元素,和上一步“决策”变量中“已破产”的结果相连接,在其中将客户变量的名称字段后面加上“已破产”字样

- 创建一个“快速更新”元素,更新客户变量

完成后的流程图如下:

保存为“流”类型,设置名称为“Check_and_update_bankrupt”,并启用该流。
这时,我们还不能使用它,因为这个流在使用前需要先得到一个“客户”对象。要实现这一点,就需要使用一个Visualforce页面来加载“客户”对象并调用流。
创建Visualforce页面
要将创建的“流”使用于Visualforce页面中,可以使用以下步骤:
在“设置”界面搜索“Visualforce 页面”,点击“Visualforce 页面”链接,进入Visualforce页面的一览表
点击“新建”按钮,新建Visualforce页面
设置“标签”和“名称”属性。设置名称为“Check_Bankrupt_And_Update_Name”
在“Visualforce Markup”部分删除原有的代码,改为:
<apex:page StandardController="Account">
<flow:interview name="Check_and_update_bankrupt"></flow:interview>
</apex:page>
这里使用了“flow:interview”组件调用了刚才建立的“流”,并且将页面的“StandardController”属性设置为“Account”,标明该页面和“客户”对象相联系
保存此Visualforce页面

建立按钮调用Visualforce页面
在“客户”的“按钮、链接和操作”部分,新建一个按钮,并将“内容源”设置为“Visualforce页面”。
系统会自动检测所有的Visualforce页面,并在下拉列表中显示“StandardController”属性为“Account”的页面。
在下拉列表中选择刚才建立的页面,保存。

然后将此按钮添加到“客户”的页面布局。

这样,用户在客户的详细信息页面点击“检查破产并更新名称”按钮,就可以使用流了。
将参数传入流
现在还差最后一步工作,就是将按钮所在的客户页面的客户变量传入流中,让流知道哪个“客户”对象需要被检查和更新。
编辑刚才建立的Visualforce页面,在“flow:interview”组件中进行如下修改:
<apex:page StandardController="Account">
<flow:interview name="Check_and_update_bankrupt">
<apex:param name="AccountVar" value="{!account}"/>
</flow:interview>
</apex:page>
从上面的代码中可以看到,我们使用了“apex:param”标签来设置流中使用的变量“AccountVar”。
但是这时,如果在客户页面中点击刚才建立的按钮,会直接出现错误。当我们检查调试日志时,会发现这样的错误信息:“流无法访问AccountVar.Bankrupt__c的值”。
这是因为我们在Visualforce页面中通过标准的“Account”控制器传入参数时,标准的控制器并不会调用“客户”对象下面的字段,从而无法检查“Bankrupt__c”的值。
这时,我们需要新建一个Apex类,作为标准“Account”控制器的扩展,在其中要求系统调用“Name”和“Bankrupt__c”字段的值。新建的Apex类如下:
public class AccountCheckBankruptExtension {
private final Account acc;
public AccountCheckBankruptExtension(ApexPages.StandardController stdController) {
stdController.addFields(new List<String>{'Name', 'Bankrupt__c'});
this.acc = (Account)stdController.getRecord();
}
}
然后将刚才的Visualforce页面修改为:
<apex:page StandardController="Account" Extensions="AccountCheckBankruptExtension">
<flow:interview name="Check_and_update_bankrupt">
<apex:param name="AccountVar" value="{!account}"/>
</flow:interview>
</apex:page>
这时,在“是否破产”值为“真”的客户页面点击“检查破产并更新名称”按钮,就可以运行流了。
设置返回跳转链接
虽然流可以顺利运行了,但是流的执行是在新的窗口中执行,结束后会给出“流执行完毕”的字样。为了提高用户体验,我们需要让流在运行结束后返回处理的“客户”页面,从而直接将结果展示为用户。
将刚才的Visualforce页面修改为:
<apex:page StandardController="Account" Extensions="AccountCheckBankruptExtension">
<flow:interview name="Check_and_update_bankrupt" finishLocation="{!URLFOR('/' + account.Id)}">
<apex:param name="AccountVar" value="{!account}"/>
</flow:interview>
</apex:page>
在这里,我们使用了“finishLocation”属性来设置流完成后跳转的页面,即跳转到“客户”变量详细信息页面。
执行结果
现在我们就可以检查整个过程了。
首先,进入一个客户的详细信息页面,将“是否破产”改为“真”。

然后点击“检查破产并更新名称”按钮,会弹出一个新的页面。这就是刚才建立的Visualforce页面。在其中,流将会被执行。结束后,跳转到刚才的客户页面。

可以看到,“客户”的“名称”部分已经被加入了“(已破产)”的字样。流执行成功了。
扩展知识
流的变量设定
在流中新建“SObject变量”时,需要将变量的“输入/输出类型”设置为“输入和输出”。否则,此变量有可能无法被Visualforce页面和相应的控制器调用。
在Apex代码中使用Flow.Interview类
在Apex代码中使用Flow.Interview类可以直接引用执行的流的实例,并且可以使用getVariableValue()函数来得到流中的变量的值。
比如上述的示例中,将Apex代码改为:
public class AccountCheckBankruptExtension {
public Flow.Interview.Check_and_update_bankrupt flowInstance {get; set;}
private final Account acc;
public AccountCheckBankruptExtension(ApexPages.StandardController stdController) {
stdController.addFields(new List<String>{'Name', 'Bankrupt__c'});
this.acc = (Account)stdController.getRecord();
}
public String getAccName() {
Account accInFlow = (Account) flowInstance.getVariableValue('AccountVar');
return accInFlow.Name;
}
}
在代码中增加了一个变量“flowInstance”,类型是“Flow.Interview.流的名字”。同时也增加了一个函数getAccName(),使用了getVariableValue()函数得到流中的“客户”变量的名称。
将Visualforce页面的代码改为:
<apex:page StandardController="Account" Extensions="AccountCheckBankruptExtension">
<flow:interview name="Check_and_update_bankrupt" interview="{!flowInstance}">
<apex:param name="AccountVar" value="{!account}"/>
</flow:interview>
<apex:outputtext>客户名称:{!accName}</apex:outputtext>
</apex:page>
这样,我们成功的得到了客户的名称,显示在页面底部。

在Visualforce页面中使用Visual Flow的更多相关文章
- Visualforce 页面的生命周期
了解 Visualforce 页面的生命周期可以让我们明白其各个元素的执行顺序.改变逻辑,从而提高开发效率,避免不必要的错误. 在官方文档中有详细的讲解.本文摘取其中的要点,作为一个总结. Visua ...
- Salesforce小知识:在简档中设置Visualforce页面的权限
简档(Profile)中的 Visualforce 页面访问权限 在Salesforce中,对于自定义的简档,可以设置"Visualforce 页面访问"的权限. Visualfo ...
- Visual Studio 2013新建ASP.NET项目使用Empty模板,在页面中使用验证控件出错的解决方案
Visual Studio 2013新建ASP.NET项目使用Empty模板,在页面中使用验证控件,运行页面,会出现如下的错误: 错误原因 VisualStudio 2012(或2013) WebFo ...
- Visual Flow 简介
Visual Flow(流) Salesforce提供了几种自动化流程工具,其中的Visual Flow(流)可以用来实现用户界面和逻辑,并对数据进行CRUD(Create 创建,Read 读取,Up ...
- 项目中Ajax调用ashx页面中的Function的实战
前台页面: 使用几个display=none的空间存储DropdownList中的值,点击Search Button后刷新页面再次给DropdownList赋值使用 <%@ Page Langu ...
- 如何添加地图控件到Windows Phone 8的页面中
原文 如何添加地图控件到Windows Phone 8的页面中 本主题介绍了各种方法来添加一个地图控件到Windows Phone 8的项目.该地图控件在Windows Phone的SDK 8.0的库 ...
- 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- C#反射实现 C# 反射 判断类的延伸类型 使用代码生成工具Database2Sharp快速生成工作流模块控制器和视图代码 C# ADO.NET的SqlDataReader对象,判断是否包含指定字段 页面中添加锚点的几种方式 .net 简单实用Log4net(多个日志配置文件) C# 常用小点
C#反射实现 一.反射概念: 1.概念: 反射,通俗的讲就是我们在只知道一个对象的内部而不了解内部结构的情况下,通过反射这个技术可以使我们明确这个对象的内部实现. 在.NET中,反射是重要的机制, ...
- ToolkitScriptManager vs. ScriptManager 关于“只能向页面中添加 ScriptManager 的一个实例”讨论
在使用ASP.NET设计AJAX功能网页时,需要首先声明ToolkitScriptManager或者ScriptManager控件,这些全局的脚本核心控制,然后才能使用众多的AJAX控件.如果没有创建 ...
随机推荐
- 面试时遇到的题目。正则,replace()
function Fn(str){ this.str = str; } Fn.prototype.format = function(){ var arg = arguments; var dd = ...
- Android网络请求与数据解析,使用Gson和GsonFormat解析复杂Json数据
版权声明:未经博主允许不得转载 一:简介 [达叔有道]软件技术人员,时代作者,从 Android 到全栈之路,我相信你也可以!阅读他的文章,会上瘾!You and me, we are family ...
- iptables概述
[参考文章]:iptables详解-朱双印个人日志 [参考文章]:linux iptables详解--个人笔记 [参考文章]:iptables详解--转 [参考文章]:linux下IPTABLES配置 ...
- @RequestParam加不加的区别
感觉@撸码识途 https://www.cnblogs.com/tinyj/p/9786131.html 加上的情况: @RequestMapping("demo") public ...
- PHP-----浅谈垃圾回收机制
前言 大多数编程语言都会有自身的垃圾回收机制,php也不例外.经常听很多人说gc,也就是垃圾回收器,全程为Garbage Collection. 在php5.3之前,是不包括垃圾回收机制的,也没有专门 ...
- F#周报2019年第17期
新闻 .NET版本的Apache Spark Apache Spark预览版介绍 F# Apache Spark示例 微软Build 2019大会(5月6日至8日) Rider用于F#的解决方案内的重 ...
- 关于 Nginx 配置 WebSocket 400 问题
今天把项目升级了 asp.net core 到 2.1 的版本,使用了 signalr 的功能,由于阿里云不支持 websocket 协议,所以使用了 nginx 代理方式来解决,后续就报了一个登陆 ...
- Linux编程 2 (遍历目录cd与查看文件和目录ls)
一. 遍历目录 在 linux系统上,可以使用cd切换目录命令. 分二种路径,一是绝对文件路径,另一种是相对文件路径. 1. 绝对文件路径 在虚拟目录中采用文件路径,以虚拟目录根目录开始,相当于 ...
- Android 源码分析01_AsyncTask
[参考文献] http://blog.csdn.net/singwhatiwanna/article/details/17596225 /* * Copyright (C) 2008 The Andr ...
- Netty自带连接池的使用
一.类介绍1.ChannelPool——连接池接口 2.SimpleChannelPool——实现ChannelPool接口,简单的连接池实现 3.FixedChannelPool——继承Simple ...