在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 

 

posted @ 2013-12-05 10:58  Eric Sun  阅读(2461)  评论(0编辑  收藏  举报