剛接觸Salesforce,過程的確是比較艱難了,中文資料幾乎沒有,看英文資料學的效率卻不高,不過看了一段時間的英文資料發現本身英語水平挺高很多啊,如今看都不用工具翻譯,早知道就再次嘗試報個6級,看下能過不,嘻嘻。。。。Salesforce的開發也是MVC模式,asp.net的MVC就玩的比較多了,換個平臺一會兒沒適應過來,不過原理都同樣,接下來就介紹一下最近的學習成果吧,來看一下SF中MVC模式下視圖與控制器之間的交互,先貼控制器和視圖的代碼,下面有詳細講解。css
apex視圖代碼以下:html
<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請求提示區"> <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="功能區"> <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>
而後下面是控制器的代碼:jquery
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); } }
大概效果圖就以下:ajax
大體描述下這個頁面和控制器作了什麼,首先點擊選擇微信用戶,而後出現一個dialog選擇框(jQuery ui風格),選上對應的微信用戶後,便會在上圖右下角出現對應的選擇,點擊刪除操做,便會刪除掉對應行,在向控制器get數據和post請求的時候(Ajax),請求的時候在請求提示區會有對應的正在請求數據的提示。整個過程都是AJAX,卻徹底不是用js作到的,至關方便,固然也支持經過js去完成,最後也大體說明下。數據庫
當點擊選擇微信號按鈕出現一個dialog,這個就很少講,直接js打開,只不過前面須要引用jquery ui的js和css瀏覽器
dialog的代碼是這樣構成的。微信
<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中是經過上面這樣的寫法進行數據填充的,其中<apex:pageBlockTable value="{!GetUserList}" var="glist"> value中的值即是對應到控制器中的GetUserList,這個變量類型是List<wechatuser__c>,因此當頁面加載完的時候,若是GetUserList有值的話,便會循環填充滿pageBlockTable了,控制器在構造函數中便已經查了數據庫,並賦值在這個變量中,另外<apex:variable value="{!0}" var="rowNum2"/>這個我我的理解是一個會根據pageBlockTable中記錄條數,進行遞增的一個變量,這裏我就用來給每條記錄一個序號,刪除對應的行也是經過這個變量去取得rowIndex來操做的。另外一個pageBlockTable的原理也是同樣的。網絡
在打開的dialog對話框選擇了對應的條目後,js便把選擇了的id傳到控制器,使用的是actionfunctionasp.net
<apex:actionfunction reRender="AjaxBlock" status="adding" immediate="true" action="{!GetChoose}" name="GetChoose" > <apex:param name="ChooseParam" assignTo="{!Choose}" value=""/> </apex:actionfunction>
在actionfunction中能夠定義apex: param 參數傳遞過去,而assignTo這個attribute則是對應到了控制器裏面的Choose變量,變量有get和set方法,這樣,當調用GetChoose(choose.join(';')) 便把想傳遞的參數直接到了控制器裏面的Choose去,這裏是我我的以爲挺有趣的。緊接着即是調用數據庫把對應記錄查出來,而後wechatuserList.add(model); 這樣視圖這邊便會刷新AjaxBlock中的數據,這裏就要注意了,若是你以爲僅僅更新wechatuserList便會讓視圖綁定了這個變量的table也進行刷新的話,你就錯了,沒有進行過處理的話,是會刷新整個頁面,那麼頁面是新的,數據也就是新的了,剛纔傳過去的id數據也對應丟失,這樣固然不是咱們想要的。函數
在ajax請求的過程當中,若是實現 1.讓用戶知道正在請求數據,頁面不刷新 2.請求完後,僅僅刷新想要刷新的部分呢。 第一個問題:在actionfunction中不是有一個status屬性嗎,注意看 它對應的是
<apex:outputPanel > <apex:actionStatus startStyle="font-size:40px;color:red;" stopStyle="font-size:30px;" startText="正在添加" id="adding" stopText="添加完成"/> </apex:outputPanel>
看屬性也就很明顯,在Ajax請求過程當中status屬性是用來通知用戶瀏覽器正在請求某個操做(若是網絡卡的話,不卡固然這個信息也不會看到),startText和stopText的值即是經過改變對應的值來告知ajax請求的過程和完成的狀態。問題二:對於actionfunction中的reRender屬性,即是指定須要ajax刷新的區域,相似這個例子,考慮ajax請求完成後,更新了wechatuserList的值,而視圖中的pageBlockTable恰好綁定了這個變量,如此,ajax請求完後,咱們但願刷新這個pageBlockTable來顯示最新的狀態,因而我用一個div或者ouputPanel來包住這個table,而後賦值一個id,再把這個id給到actionfunction的attribute reRender。這樣,在actionfunction執行完後,便會刷新對應的區域,實現了Ajax的請求。
同樣的道理,點擊commandLink 帶上了apex: param 參數,帶上須要刪除的行rowIndex,在點擊了刪除按鈕後,也是刪除List<wechatuser__c>的值,而後ajax刷新AjaxBlock。
總結一下,當視圖須要訪問控制器的某個方法或者變量(變量須要get和set),只須要{!函數名(或者變量名)} 這樣即可以訪問控制器,若是須要帶上參數便在標籤中帶上<apex: param> 能夠經過綁定控制器的變量和視圖中的pageblocktable來實現數據的同步,若是改變了對應的值,刷新視圖對應的部分即可以。固然除了這樣的方法實現控制器和視圖的通信和Ajax請求,咱們也能夠經過js來完成,下面代碼即是在js中調用控制器的函數,並在回調函數中進行對應的處理。
SendMessageController.AutoAjax( Param, function(result, event){ if (event.status) {
//這裏是請求完成處理的事情 }
//這裏是當請求狀態不正常(錯誤或者網絡延遲),處理區域
}, {escape: true}//這個是html編碼的轉義開關,以前的一篇博客有講過 );
js方法中SendMessageController即是控制器名,.後面的即是對應的方法名,控制器的方法前須要帶上@RemoteAction標籤,函數第一個即是傳過去的參數,若是有多個參數,用逗號隔開即可以,有function的即是回調函數,最後那個是html轉義的標誌,前面有講到,大概的控制器和視圖交互就是這樣,應該還不全,也是研究了一個星期的成果而已,後面再慢慢完善吧。