在Visualforce page中用自带的控件实现Ajax回调后台方法(并且可以用js去动态给parameters赋值)

这里用的组合是:apex:commandLink  + apex:actionFunction + apex:outputPanel

这里的 apex:commandLink 和 apex:actionFunction 都可以通过 action 来指定Ajax所回调的后台方法,

方案一:

其中 apex:commandLink 充当直接回调后台方法的控件,  用 oncomplete 指定执行完后台方法之后所调用的 actionFunction

其中 apex:actionFunction 的 name 标识actionFunction的名字,实质上是一个JavaScript方法,其他地方可以直接进行调用,这里用apex:commandLink的oncomplete方法调用, rerender 指定所要刷新的 apex:outputPanel, oncomplete 指定刷新完outputPanel之后所调用的JavaScript方法

1):后台class的变量和类定义

public List<SalesPersonSales> personSalesTop10_MTD { get; set; }

public class SalesPersonSales implements Comparable{
public string OwnerName {get;set;}
public string OwnerId {get;set;}
public decimal TotalSales {get;set;}
public decimal TotalGP {get;set;} public SalesPersonSales(string name, string id, decimal sales, decimal gp){
OwnerName = name;
OwnerId = id;
TotalSales = sales;
TotalGP = gp;
} public Integer compareTo(Object objToCompare){
return (((SalesPersonSales)objToCompare).TotalSales - TotalSales).intValue();
}
}

2):前台page的控件布局与JavaScript方法

<apex:form id="theform">
<apex:outputPanel id="SalespeopleReportPanel">
<apex:outputPanel id="SalespeopleReportMTDPanel">
<table>
<thead>
<tr>
<th>Top 10 Salespeople MTD</th>
<th>Sales</th>
<th>GP$</th>
</tr>
</thead>
<tbody>
<apex:repeat value="{!personSalesTop10_MTD}" var="Item_Obj">
<tr>
<td>
<apex:outputLink value="../apex/DashboardReportDetail">
{!Item_Obj.OwnerName}
<apex:param name="oid" value="{!Item_Obj.OwnerId}"/>
<apex:param name="timetype" value="MTD"/>
</apex:outputLink>
</td>
<td>
<apex:outputText value="{0,number,$#,###.##}" >
<apex:param value="{!Item_Obj.TotalSales}" />
</apex:outputText>
</td>
<td>
<apex:outputText value="{0,number,$#,###.##}" >
<apex:param value="{!Item_Obj.TotalGP}" />
</apex:outputText>
</td>
</tr>
</apex:repeat>
<tr>
<td>
<apex:commandLink action="{!LoadAllSalespeople}" oncomplete="rerenderSalespeopleReportMTDPanel();" status="sstatus">
Show All
<apex:param value="All" name="topType"/>
<apex:param value="MTD" name="timeType"/>
</apex:commandLink>
</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</apex:outputPanel>
<apex:actionFunction name="rerenderSalespeopleReportMTDPanel" rerender="SalespeopleReportMTDPanel" oncomplete="refreshSalespeopleDashboardChart();"/>
</apex:outputPanel>
</apex:form> <script type="text/javascript"> function refreshSalespeopleDashboardChart(){
// Your JS function....
} </script>

【 注:如果Ajax回调的方法更新了后台的某个变量,前台JS方法中想要直接用{!myVariable}这种方法是获取不到更新之后的值的,这样的处理方式细想一下还是很合理的。】

【 要想获取更新之后的值的话,要将变量的值存储到更新的outputPanel中的某个控件中,然后通过JS的方法获取更新之后控件的内容就可以了。】

3):Ajax回调的后台方法

public pagereference LoadAllSalespeople(){
string topType = ApexPages.currentPage().getParameters().get('topType');
string timeType = ApexPages.currentPage().getParameters().get('timeType');
if(timeType == 'MTD'){
// to do
}
else{
// to do
}
return null;
}

上面的这种方式有一个很大的弊端,就是不能够动态的给parameter赋值,如果想满足这点请看如下方案

方案二:

其中 apex:commandLink 仅当做一个触发器,通过前台JS方法去调用apex:actionFunction所对应的后台方法,这个JS方法做了一个非常重要的事情就是动态的传递Parameter的值。形式为:actionFunction的名字(param1, param2, ...)

其中 apex:actionFunction 的 name 标识actionFunction的名字,实质上是一个JavaScript方法,其他地方可以直接进行调用,rerender 指定所要刷新的 apex:outputPanel, oncomplete 指定刷新完outputPanel之后所调用的JavaScript方法

那么所对应的Apex Page代码如下所示:

<apex:form id="theform">
<apex:outputPanel id="SalespeopleReportPanel">
<apex:outputPanel id="SalespeopleReportMTDPanel">
<table>
<thead>
<tr>
<th>Top 10 Salespeople MTD</th>
<th>Sales</th>
<th>GP$</th>
</tr>
</thead>
<tbody>
<apex:repeat value="{!personSalesTop10_MTD}" var="Item_Obj">
<tr>
<td>
<apex:outputLink value="../apex/DashboardReportDetail">
{!Item_Obj.OwnerName}
<apex:param name="oid" value="{!Item_Obj.OwnerId}"/>
<apex:param name="timetype" value="MTD"/>
</apex:outputLink>
</td>
<td>
<apex:outputText value="{0,number,$#,###.##}" >
<apex:param value="{!Item_Obj.TotalSales}" />
</apex:outputText>
</td>
<td>
<apex:outputText value="{0,number,$#,###.##}" >
<apex:param value="{!Item_Obj.TotalGP}" />
</apex:outputText>
</td>
</tr>
</apex:repeat>
<tr>
<td>
<apex:commandLink onclick="CallActionFunction();">Show All</apex:commandLink>
</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</apex:outputPanel>
<apex:actionFunction name="rerenderSalespeopleReportMTDPanel" action="{!LoadAllSalespeople}" rerender="SalespeopleReportMTDPanel" oncomplete="refreshSalespeopleDashboardChart();"/>
<apex:param value="All" name=""/>
<apex:param value="MTD" name=""/>
</apex:actionFunction>
</apex:outputPanel>
</apex:form> <script type="text/javascript"> function CallActionFunction(){
rerenderSalespeopleReportMTDPanel('topType', 'timeType'); // these two parameters can get automatically by js
} function refreshSalespeopleDashboardChart(){
// Your JS function....
} </script>

对比方案一和方案二:

方案一的基本代码结构(轻actionFunction,重commandLink)

<apex:outputPanel id="SalespeopleReportMTDPanel">
<apex:commandLink action="{!LoadAllSalespeople}" oncomplete="rerenderSalespeopleReportMTDPanel();">
Show All
<apex:param value="All" name="topType"/>
<apex:param value="MTD" name="timeType"/>
</apex:commandLink>
<apex:actionFunction name="rerenderSalespeopleReportMTDPanel" rerender="SalespeopleReportMTDPanel" oncomplete="refreshSalespeopleDashboardChart();"/>
</apex:outputPanel> <script type="text/javascript"> function refreshSalespeopleDashboardChart(){
// Your JS function....
} </script>

方案二的基本代码结构(轻commandLink,重actionFunction)

<apex:outputPanel id="SalespeopleReportMTDPanel">
<apex:commandLink onclick="CallActionFunction();">Show All</apex:commandLink>
<apex:actionFunction name="rerenderSalespeopleReportMTDPanel" action="{!LoadAllSalespeople}" rerender="SalespeopleReportMTDPanel" oncomplete="refreshSalespeopleDashboardChart();"/>
<apex:param value="All" name=""/>
<apex:param value="MTD" name=""/>
</apex:actionFunction>
</apex:outputPanel> <script type="text/javascript"> function CallActionFunction(){
rerenderSalespeopleReportMTDPanel('topType', 'timeType'); // these two parameters can get automatically by js
} function refreshSalespeopleDashboardChart(){
// Your JS function....
} </script>

进一步引申:

我们发现可以完全用其他控件来代替commandLink的触发器作用,来调用actionFunction所指定的后台方法,具体的代码结构如下所示:

<apex:outputPanel id="SalespeopleReportMTDPanel">
<input type="button" value="Show All" title="ShowAll" name="ShowAll" onclick="CallActionFunction();"/>
<apex:actionFunction name="rerenderSalespeopleReportMTDPanel" action="{!LoadAllSalespeople}" rerender="SalespeopleReportMTDPanel" oncomplete="refreshSalespeopleDashboardChart();"/>
<apex:param value="All" name=""/>
<apex:param value="MTD" name=""/>
</apex:actionFunction>
</apex:outputPanel> <script type="text/javascript"> function CallActionFunction(){
// other custom logic
rerenderSalespeopleReportMTDPanel('topType', 'timeType'); // these two parameters can get automatically by js
} function refreshSalespeopleDashboardChart(){
// Your JS function....
} </script>

这里附上另一种Ajax回调的方式,请看这个链接:http://www.cnblogs.com/mingmingruyuedlut/p/3385532.html

上一篇:Salesforce随笔: 将Visualforce Page导出为 Excel/CSV/txt (Display a page in Excel)


下一篇:Visualforce Page超链接