Salesforce視圖與控制器之間的交互

剛接觸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

image

大體描述下這個頁面和控制器作了什麼,首先點擊選擇微信用戶,而後出現一個dialog選擇框(jQuery ui風格),選上對應的微信用戶後,便會在上圖右下角出現對應的選擇,點擊刪除操做,便會刪除掉對應行,在向控制器get數據和post請求的時候(Ajax),請求的時候在請求提示區會有對應的正在請求數據的提示。整個過程都是AJAX,卻徹底不是用js作到的,至關方便,固然也支持經過js去完成,最後也大體說明下。數據庫

image

當點擊選擇微信號按鈕出現一個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轉義的標誌,前面有講到,大概的控制器和視圖交互就是這樣,應該還不全,也是研究了一個星期的成果而已,後面再慢慢完善吧。

相關文章
相關標籤/搜索