在本文中,我們將通過一個示例說明如何將“流”(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>
這樣,我們成功的得到了客戶的名稱,顯示在頁面底部。