Salesforce视图与控制器之间的交互
剛接觸Salesforce,過程的確是比較艱難了,中文資料幾乎沒有,看英文資料學的效率卻不高,不過看了一段時間的英文資料發(fā)現(xiàn)自己英語水平挺高不少啊,現(xiàn)在看都不用工具翻譯,早知道就再次嘗試報個6級,看下能過不,嘻嘻。。。。Salesforce的開發(fā)也是MVC模式,asp.net的MVC就玩的比較多了,換個平臺一下子沒適應(yīng)過來,不過原理都一樣,接下來就介紹一下最近的學習成果吧,來看一下SF中MVC模式下視圖與控制器之間的交互,先貼控制器和視圖的代碼,下面有詳細講解。
apex視圖代碼如下:
<apex:page Controller="SendMessageController"> <apex:stylesheet value="{!URLFOR($Resource.jQuery, 'jquery-ui.css')}" /><apex:stylesheet value="{!URLFOR($Resource.jQuery, 'mystyle.css')}" /><apex:includeScript value="{!URLFOR($Resource.jQuery, 'jquery-2.1.1.min.js')}"/><apex:includeScript value="{!URLFOR($Resource.jQuery, 'jquery-ui.js')}"/> <apex:form ><apex:pageBlock title="視圖與控制器的交互"><apex:pageBlockSection title="Ajax請求提示區(qū)"><apex:outputPanel ><apex:actionStatus startStyle="font-size:40px;color:red;" stopStyle="font-size:30px;" startText="正在添加" id="adding" stopText="添加完成"/></apex:outputPanel><apex:outputPanel ><apex:actionStatus startStyle="font-size:40px;color:red;" stopStyle="font-size:30px;" startText="正在刪除" id="deleting" stopText="刪除完成"/></apex:outputPanel></apex:pageBlockSection><apex:pageBlockSection title="功能區(qū)"><input type="button" onclick="OpenDialog()" id="addUser" value="選擇微信用戶(按鈕)"/><apex:outputPanel id="AjaxBlock"><apex:variable value="{!0}" var="rowNum"/><apex:pageBlockTable value="{!wechatuserList}" var="wu"><apex:column headerValue="序號"><apex:outputText value="{0}"><apex:param value="{!rowNum+1}"/></apex:outputText></apex:column><apex:column headerValue="操作"><apex:commandLink value="刪除" action="{!deleteRow}" reRender="AjaxBlock" status="deleting" style="color:blue"><apex:param name="rowIndex" value="{!rowNum}"/></apex:commandLink></apex:column><apex:column headerValue="昵稱"><apex:outputField value="{!wu.Name}"/></apex:column><apex:column headerValue="微信號"><apex:variable var="rowNum" value="{!rowNum+1}"/><apex:outputField value="{!wu.openid__c}"/></apex:column><apex:column headerValue="是否有效"><apex:outputField value="{!wu.validornot__c}"/></apex:column></apex:pageBlockTable></apex:outputPanel></apex:pageBlockSection></apex:pageBlock><apex:actionfunction reRender="AjaxBlock" status="adding" immediate="true" action="{!GetChoose}" name="GetChoose" ><apex:param name="ChooseParam" assignTo="{!Choose}" value=""/></apex:actionfunction><div id="SelectWechatUser" style="height:470px;overflow-Y:auto;"><apex:outputPanel ><input type="button" value="確認選擇" onclick="ComfirmChoost()" class="btn"/></apex:outputPanel><apex:pageBlock ><apex:variable value="{!0}" var="rowNum2"/><apex:pageBlockTable value="{!GetUserList}" var="glist"><apex:column headerValue="選擇" style="width:5%"><input type="checkBox" value="{!glist.Id}" name="checkedPro"/></apex:column><apex:column headerValue="序號" style="width:5%;text-align:center;"><apex:outputText value="{0}" ><apex:param value="{!rowNum2+1}"/></apex:outputText></apex:column><apex:column headerValue="昵稱" style="width:30%"><apex:outputField value="{!glist.Name}" style="width:100%"/></apex:column><apex:column headerValue="微信號" style="width:30%"><apex:outputField value="{!glist.openid__c}" style="width:100%"/><apex:variable var="rowNum2" value="{!rowNum2+1}"/></apex:column><apex:column headerValue="是否有效" style="width:30%"><apex:outputField value="{!glist.validornot__c}" style="width:100%"/></apex:column></apex:pageBlockTable></apex:pageBlock></div> </apex:form><script>var dialog;$(function () {dialog=jQuery("#SelectWechatUser").dialog({autoOpen: false,height:550,width: 900,modal: true});});function OpenDialog(){jQuery("#SelectWechatUser").dialog("open");}function ComfirmChoost(){var choose=[];var allPro=document.getElementsByName("checkedPro");for(var i=0;i<allPro.length;i++){if(allPro[i].checked){choose.push(allPro[i].value);}}if(choose.length==0){alert("請選擇微信用戶");return;}else{jQuery("#SelectWechatUser").dialog("close");GetChoose(choose.join(';'));}}</script> </apex:page>然后下面是控制器的代碼:
public class SendMessageController {public List<wechatuser__c> GetUserList { get; set; }public String Choose{get;set;}public List<String> chooseIds{get;set;}public List<wechatuser__c> wechatuserList { get; set; }public SendMessageController(){wechatuserList=new List<wechatuser__c>();GetUserList=[select id,Name,openid__c,validornot__c from wechatuser__c];}public void GetChoose(){ if(Choose !=null ){chooseIds = Choose.split(';');System.Debug('長度:'+wechatuserList.size());for(wechatuser__c model : [select id,Name,openid__c,validornot__c from wechatuser__c WHERE id IN :chooseIds]){ wechatuserList.add(model); }System.Debug('長度:'+wechatuserList.size());}}public void deleteRow() {Integer rowIndex;rowIndex = Integer.valueOf(ApexPages.currentPage().getParameters().get('rowIndex'));wechatuserList.remove(rowIndex);} }大概效果圖就如下:
大致描述下這個頁面和控制器做了什么,首先點擊選擇微信用戶,然后出現(xiàn)一個dialog選擇框(jQuery ui風格),選上對應(yīng)的微信用戶后,便會在上圖右下角出現(xiàn)對應(yīng)的選擇,點擊刪除操作,便會刪除掉對應(yīng)行,在向控制器get數(shù)據(jù)和post請求的時候(Ajax),請求的時候在請求提示區(qū)會有對應(yīng)的正在請求數(shù)據(jù)的提示。整個過程都是AJAX,卻完全不是用js做到的,相當方便,當然也支持通過js去完成,最后也大致說明下。
當點擊選擇微信號按鈕出現(xiàn)一個dialog,這個就不多講,直接js打開,只不過前面需要引用jquery ui的js和css
dialog的代碼是這樣構(gòu)成的。
<div id="SelectWechatUser" style="height:470px;overflow-Y:auto;"><apex:outputPanel ><input type="button" value="確認選擇" onclick="ComfirmChoost()" class="btn"/></apex:outputPanel><apex:pageBlock ><apex:variable value="{!0}" var="rowNum2"/><apex:pageBlockTable value="{!GetUserList}" var="glist"><apex:column headerValue="選擇" style="width:5%"><input type="checkBox" value="{!glist.Id}" name="checkedPro"/></apex:column><apex:column headerValue="序號" style="width:5%;text-align:center;"><apex:outputText value="{0}" ><apex:param value="{!rowNum2+1}"/></apex:outputText></apex:column><apex:column headerValue="昵稱" style="width:30%"><apex:outputField value="{!glist.Name}" style="width:100%"/></apex:column><apex:column headerValue="微信號" style="width:30%"><apex:outputField value="{!glist.openid__c}" style="width:100%"/><apex:variable var="rowNum2" value="{!rowNum2+1}"/></apex:column><apex:column headerValue="是否有效" style="width:30%"><apex:outputField value="{!glist.validornot__c}" style="width:100%"/></apex:column></apex:pageBlockTable></apex:pageBlock></div>apex中是通過上面這樣的寫法進行數(shù)據(jù)填充的,其中<apex:pageBlockTable value="{!GetUserList}" var="glist">?? value中的值便是對應(yīng)到控制器中的GetUserList,這個變量類型是List<wechatuser__c>,所以當頁面加載完的時候,如果GetUserList有值的話,便會循環(huán)填充滿pageBlockTable了,控制器在構(gòu)造函數(shù)中便已經(jīng)查了數(shù)據(jù)庫,并賦值在這個變量中,另外<apex:variable value="{!0}" var="rowNum2"/>這個我個人理解是一個會根據(jù)pageBlockTable中記錄條數(shù),進行遞增的一個變量,這里我就用來給每條記錄一個序號,刪除對應(yīng)的行也是通過這個變量去取得rowIndex來操作的。另一個pageBlockTable的原理也是一樣的。
????? 在打開的dialog對話框選擇了對應(yīng)的條目后,js便把選擇了的id傳到控制器,使用的是actionfunction
<apex:actionfunction reRender="AjaxBlock" status="adding" immediate="true" action="{!GetChoose}" name="GetChoose" ><apex:param name="ChooseParam" assignTo="{!Choose}" value=""/></apex:actionfunction>在actionfunction中可以定義apex: param 參數(shù)傳遞過去,而assignTo這個attribute則是對應(yīng)到了控制器里面的Choose變量,變量有g(shù)et和set方法,這樣,當調(diào)用GetChoose(choose.join(';')) 便把想傳遞的參數(shù)直接到了控制器里面的Choose去,這里是我個人覺得挺有趣的。緊接著便是調(diào)用數(shù)據(jù)庫把對應(yīng)記錄查出來,然后wechatuserList.add(model); 這樣視圖這邊便會刷新AjaxBlock中的數(shù)據(jù),這里就要注意了,如果你覺得僅僅更新wechatuserList便會讓視圖綁定了這個變量的table也進行刷新的話,你就錯了,沒有進行過處理的話,是會刷新整個頁面,那么頁面是新的,數(shù)據(jù)也就是新的了,剛才傳過去的id數(shù)據(jù)也對應(yīng)丟失,這樣當然不是我們想要的。
???? 在ajax請求的過程中,如果實現(xiàn) 1.讓用戶知道正在請求數(shù)據(jù),頁面不刷新? 2.請求完后,僅僅刷新想要刷新的部分呢。 第一個問題:在actionfunction中不是有一個status屬性嗎,注意看 它對應(yīng)的是
<apex:outputPanel ><apex:actionStatus startStyle="font-size:40px;color:red;" stopStyle="font-size:30px;" startText="正在添加" id="adding" stopText="添加完成"/></apex:outputPanel>看屬性也就很明顯,在Ajax請求過程中status屬性是用來通知用戶瀏覽器正在請求某個操作(如果網(wǎng)絡(luò)卡的話,不卡當然這個信息也不會看到),startText和stopText的值便是通過改變對應(yīng)的值來告知ajax請求的過程和完成的狀態(tài)。問題二:對于actionfunction中的reRender屬性,便是指定需要ajax刷新的區(qū)域,類似這個例子,考慮ajax請求完成后,更新了wechatuserList的值,而視圖中的pageBlockTable剛好綁定了這個變量,如此,ajax請求完后,我們希望刷新這個pageBlockTable來顯示最新的狀態(tài),于是我用一個div或者ouputPanel來包住這個table,然后賦值一個id,再把這個id給到actionfunction的attribute? reRender。這樣,在actionfunction執(zhí)行完后,便會刷新對應(yīng)的區(qū)域,實現(xiàn)了Ajax的請求。
???? 一樣的道理,點擊commandLink 帶上了apex: param 參數(shù),帶上需要刪除的行rowIndex,在點擊了刪除按鈕后,也是刪除List<wechatuser__c>的值,然后ajax刷新AjaxBlock。
???? 總結(jié)一下,當視圖需要訪問控制器的某個方法或者變量(變量需要get和set),只需要{!函數(shù)名(或者變量名)}? 這樣便可以訪問控制器,如果需要帶上參數(shù)便在標簽中帶上<apex: param>? 可以通過綁定控制器的變量和視圖中的pageblocktable來實現(xiàn)數(shù)據(jù)的同步,如果改變了對應(yīng)的值,刷新視圖對應(yīng)的部分便可以。當然除了這樣的方法實現(xiàn)控制器和視圖的通訊和Ajax請求,我們也可以通過js來完成,下面代碼便是在js中調(diào)用控制器的函數(shù),并在回調(diào)函數(shù)中進行對應(yīng)的處理。
SendMessageController.AutoAjax(Param,function(result, event){if (event.status) { //這里是請求完成處理的事情} //這里是當請求狀態(tài)不正常(錯誤或者網(wǎng)絡(luò)延遲),處理區(qū)域 },{escape: true}//這個是html編碼的轉(zhuǎn)義開關(guān),之前的一篇博客有講過);js方法中SendMessageController便是控制器名,.后面的便是對應(yīng)的方法名,控制器的方法前需要帶上@RemoteAction標簽,函數(shù)第一個便是傳過去的參數(shù),如果有多個參數(shù),用逗號隔開便可以,有function的便是回調(diào)函數(shù),最后那個是html轉(zhuǎn)義的標志,前面有講到,大概的控制器和視圖交互就是這樣,應(yīng)該還不全,也是研究了一個星期的成果而已,后面再慢慢完善吧。
轉(zhuǎn)載于:https://www.cnblogs.com/xmfdsh/p/4511045.html
總結(jié)
以上是生活随笔為你收集整理的Salesforce视图与控制器之间的交互的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenSceneGraph学习笔记
- 下一篇: spring事务配置