在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