Salesforce视图与控制器之间的交互

刚接触Salesforce,过程的确是比较艰难了,中文资料几乎没有,看英文资料学的效率却不高,不过看了一段时间的英文资料发现自己英语水平挺高不少啊,现在看都不用工具翻译,早知道就再次尝试报个6级,看下能过不,嘻嘻。。。。Salesforce的开发也是MVC模式,asp.net的MVC就玩的比较多了,换个平台一下子没适应过来,不过原理都一样,接下来就介绍一下最近的学习成果吧,来看一下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请求提示区">
    <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>

然后下面是控制器的代码:

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);
    }
}

大概效果图就如下:

大致描述下这个页面和控制器做了什么,首先点击选择微信用户,然后出现一个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传到控制器,使用的是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 参数传递过去,而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转义的标志,前面有讲到,大概的控制器和视图交互就是这样,应该还不全,也是研究了一个星期的成果而已,后面再慢慢完善吧。

时间: 2024-10-06 00:45:19

Salesforce视图与控制器之间的交互的相关文章

[email&#160;protected]指令与控制器之间的交互demo

1.index.html: <!DOCTYPE HTML><html ng-app="app"><head>    <title>custom-directive</title>    <meta charset="utf-8">        <link rel="stylesheet" href="../css/bootstrap.css">

AngularJs-指令和指令之间的交互(动感超人)

前言: 上节我们学习到了指令和控制器之间的交互,通过给指令添加动作,调用了控制器中的方法.本节我们学习指令和指令之间是如何交互的,我们通过一个小游戏来和大家一起学习,听大漠老师说这是国外的人写的demo,我们可以借鉴学习. 1,动感超人 上面的三个按钮,代表三个超人,在此想问下,哪些想看超人的朋友们是不是有种被骗了的感觉? 当我们的鼠标移动到哪个超人的身上的时候,就会输入这个超人所拥有的超能力(力量 + 敏捷 + 发光) <!DOCTYPE html> <html ng-app=&quo

ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第二章:利用模型类创建视图、控制器和数据库

在这一章中,我们将直接进入项目,并且为产品和分类添加一些基本的模型类.我们将在Entity Framework的代码优先模式下,利用这些模型类创建一个数据库.我们还将学习如何在代码中创建数据库上下文类.指定数据库连接字符串以及创建一个数据库.最后,我们还将添加视图和控制器来管理和显式产品和分类数据. 注意:如果你想按照本章的代码编写示例,你必须完成第一章或者直接从www.apress.com下载第一章的源代码. 2.1 添加模型类 Entity Framework的代码优先模式允许我们从模型类创

简单讲解MVC(视图/模型/控制器)

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑.MVC被独特的发展起来用于映射传统的输入.处理和输出功能在一个逻辑的图形化用户界面的结构中. 视图 视图是用户看到并与之交互的界面.对老式的Web应用程序来说,视图就是由HTML元素组成的界面,在新式的W

控制器之间反向传值

控制器之间反向传值 委托(代理) 首先我们定下一个协议protocol 1. #import <Foundation/Foundation.h>2.3. @protocol ChangeText <NSObject>4.5. -(void)changeText:(NSString *)str;6. @end 控制器a遵守协议ChangeText,并实现协议的方法,控制器b公开自己的一个遵守协议ChangeText的属性delegate,在控制器a的视图转到控制器b的视图时,b.de

【UIKit】控制器之间的切换1 【Modal】

[Modal][?Code] 1.首先有2个控制器,并且都拥有视图界面. ? 2.点击登录后,第二个页面会从下方上移,那就得在第一个界面中首先创建另外一个界面.然后转向 首先得加载一个协议,这个就是第二个页面的代理. <LoginViewControllerDelegate> 2).点击登录进行转向 - (IBAction)Login { // 初始化控制器 LoginViewController *login=[[LoginViewController alloc]init]; login.

MVC 模型、视图、控制器

所谓模型,就是在MVC设计模式中需要被显示的数据.在通常情况下,该模型需要从数据库中读取数据.保存模型的状态等,提供数据的访问方法及数据维护. 例如,对于SQL Server中数据库NorthWind的表Products来说,一个Product对象就是一个模型,该对象需要读取数据库中的信息,并对该数据表进行查询.添加.修改等操作.对于一个比较小型的应用程序而言,模型也许只是概念上的,假如一个应用程序需要读取数据,然后显示在用户界面上,而在该应用程序中并不存在一个物理上的数据模型或者相关的类,那么

Android学习笔记(十六)——碎片之间进行交互(附源码)

碎片之间进行交互 点击下载源码 很多时候,一个活动中包含一个或者多个碎片,它们彼此协作,向用户展示一个一致的UI.在这种情况下,碎片之间能进行通信并交换数据十分重要. 1.使用上一篇中创建的同一个项目,在fragment.xml中添加TextView的标识id: android:id="@+id/lblFragment1" 2.在fragment2.xml中添加一个Button,用于与fragment1进行交互: <Button android:id="@+id/btn

多控制器之间的跳转

1>  什么是多控制器之间的跳转? 在一个 APP 中,会存在多个控制器,多个控制器的存在就会存在控制器的跳转问题. 2>  包含:连线跳转,modal 方式以及navigationController/tabBarontroller方式 连线跳转:根据绑定的 ID 进行控制器的跳转 连线跳转的分类: > 自动型:点击控件后,自动跳转到下一个控制器(action – push 方式) > 手动型:需要借助于代码手动完成. 手动型,是指从来源控制器拖到目标控制器.(manual –