salesforce 零基础学习(六十四)页面初始化时实现DML操作

有的时候我们往往会遇到此种类似的需求:用户在访问某个详细的记录时,需要记录一下什么时候哪个用户访问过此页面,也就是说进入此页面时,需要插入一条记录到表中,表有用户信息,record id,sObject name以及vf page name.但是对于salesforce,不允许在controller的构造函数中进行DML操作,此种情况推荐采用两种方式实现此功能:

一.使用apex:page的action属性

1. DetailGoodsUseAjaxToolkitController:实现数据的初始化以及提供方法实现log记录的插入操作

 1 public with sharing class DetailGoodsUseAjaxToolkitController {
 2     
 3     public DetailGoodsUseAjaxToolkitController() {
 4         initData();
 5     }
 6     
 7     private Map<String,String> params;
 8     
 9     public Goods__c goods{get;set;}
10     
11     private void initData() {
12         params = ApexPages.currentPage().getParameters();
13         String goodsId = params.get('id'); 
14         goods = [SELECT Goods_Code_Unique__c, GoodsBrand__c, GoodsCostPrice__c, GoodsDescribe__c,
15                          GoodsName__c, GoodsPrice__c, GoodsProfit__c,Id FROM Goods__c 
16                          where id=:goodsId];
17     }
18     
19     
20     /*
21     * 用于apex:page绑定的action,执行完构造函数以后执行此方法
22     */
23     public void createLog() {
24         Log_Info__c log = new Log_Info__c();
25         log.Access_Date__c = system.now();
26         PageReference pr = ApexPages.currentPage();
27         String relatedURL = pr.getUrl();
28         Integer startIndex = relatedURL.lastIndexOf('/') + 1;
29         Integer endIndex = relatedURL.indexOf('?') == -1 ? relatedURL.length() : relatedURL.indexOf('?');
30         String pageName = relatedURL.substring(startIndex,endIndex);
31         log.Access_Page__c = pageName;
32         log.Accessor__c = UserInfo.getUserId();
33         insert log;
34     }
35 }

2.DetailGoodsUseAction.page:实现页面绘画以及通过action调用后台方法实现DML操作

 1 <apex:page controller="DetailGoodsUseAjaxToolkitController" action="{!createLog}">
 2     <apex:form > 
 3         <apex:pageBlock title="Goods Information"> 
 4             <apex:pageBlockSection title="Goods Basic Information"> 
 5                 <apex:outputText id="GoodsUniqueCode" value="{!goods.Goods_Code_Unique__c}"/>
 6                 <apex:outputText id="GoodsName" value="{!goods.GoodsName__c}"/> 
 7                 <apex:outputText id="GoodsPrice" value="{!goods.GoodsPrice__c}"/> 
 8                 <apex:outputText id="GoodsCostPrice" value="{!goods.GoodsCostPrice__c}"/> 
 9             </apex:pageBlockSection> 
10         </apex:pageBlock> 
11     </apex:form> 
12 </apex:page>

二.使用ajax toolkit

 ajax toolkit API : https://resources.docs.salesforce.com/204/latest/en-us/sfdc/pdf/apex_ajax.pdf

相关核心API:https://developer.salesforce.com/docs/atlas.en-us.204.0.api.meta/api/sforce_api_calls_list.htm

ajax toolkit基于SOAP 的API,简单的说即通过js调用soap api实现少量的数据的页面展示或者对少量数据进行DML操作,如果对于大数据处理,别使用此种方式。

 使用ajax toolkit主要三个步骤:

1.Connecting to the API :

  针对非自定义button的引入

<apex:page> 
    <script src="../../soap/ajax/38.0/connection.js" type="text/javascript"></script> 
    <script> 
        sforce.connection.sessionId='{!GETSESSIONID()}'; 
        ... 
    </script> 
    ... 
</apex:page>

针对自定义onclick javascript按钮的引入:

<body> 
    {!requireScript("/soap/ajax/38.0/connection.js")} ... 

2.Embedding API Calls in JavaScript :在javascript中嵌入API,然后通过回掉函数进行函数成功或者失败的处理操作;

3.Processing Results:对结果进行处理。 如果进行的是查询操作,可以对查询列表进行相关处理或者执行queryMore等操作,如果是进行DML操作可以判断是否执行成功等。

使用Ajax Toolkit可以实现同步或者异步的调用,详情参看上方PDF。

官方demo如下:

 1 <apex:page > 
 2     <script type="text/javascript"> 
 3         var __sfdcSessionId = '{!GETSESSIONID()}';
 4     </script> 
 5     <script src="../../soap/ajax/38.0/connection.js" type="text/javascript"></script> 
 6     <script type="text/javascript"> 
 7         window.onload = setupPage; 
 8         function setupPage() { //function contains all code to execute after page is rendered 
 9             var state = { //state that you need when the callback is called 
10                 output : document.getElementById("output"), 
11                 startTime : new Date().getTime()
12             }; 
13             var callback = { //call layoutResult if the request is successful 
14                 onSuccess: layoutResults, //call queryFailed if the api request fails 
15                 onFailure: queryFailed, 
16                 source: state
17             };
18             sforce.connection.query( "Select Id, Name, Industry From Account order by Industry", callback);
19         } 
20 
21         function queryFailed(error, source) { 
22             source.output.innerHTML = "An error has occurred: " + error; 
23         } 
24         /** * This method will be called when the toolkit receives a successful 
25         * response from the server. 
26         * @queryResult - result that server returned 
27         * @source - state passed into the query method call. 
28         */ 
29         function layoutResults(queryResult, source) { 
30             if (queryResult.size > 0) { 
31                 var output = ""; //get the records array 
32                 var records = queryResult.getArray('records'); //loop through the records and construct html string 
33                 for (var i = 0; i < records.length; i++) { 
34                     var account = records[i]; 
35                     output += account.Id + " " + account.Name + " [Industry - " + account.Industry + "]<br>"; 
36                 } //render the generated html string 
37                 source.output.innerHTML = output; 
38             } 
39         } 
40     </script>
41 
42     <div id="output"> </div> 
43 </apex:page>

通过demo可以看出:通过api先进行query操作查出Industry表数据,然后进行callback回掉,callback执行success和error的相关处理从而实现数据的展示。

通过ajax toolkit实现log数据的插入

 1 <apex:page controller="DetailGoodsUseAjaxToolkitController">
 2     <apex:form > 
 3         <apex:pageBlock title="Goods Information"> 
 4             <apex:pageBlockSection title="Goods Basic Information"> 
 5                 <apex:outputText id="GoodsUniqueCode" value="{!goods.Goods_Code_Unique__c}"/>
 6                 <apex:outputText id="GoodsName" value="{!goods.GoodsName__c}"/> 
 7                 <apex:outputText id="GoodsPrice" value="{!goods.GoodsPrice__c}"/> 
 8                 <apex:outputText id="GoodsCostPrice" value="{!goods.GoodsCostPrice__c}"/> 
 9             </apex:pageBlockSection> 
10         </apex:pageBlock> 
11     </apex:form> 
12     
13     <script type="text/javascript"> 
14         var __sfdcSessionId = '{!GETSESSIONID()}';
15     </script> 
16     <script src="/soap/ajax/38.0/connection.js" type="text/javascript"></script> 
17     <script src="/soap/ajax/38.0/apex.js" type="text/javascript"></script> 
18     <script type="text/javascript"> 
19         window.onload = setupPage; 
20         function setupPage() { 
21             var logInfo = new sforce.SObject("Log_Info__c");
22             logInfo.Accessor__c = "{!$User.Id}";
23             var accessDate = new Date("{!NOW()}");
24             logInfo.Access_Date__c = accessDate;
25             logInfo.Access_Page__c = "{!$CurrentPage.Name}";
26             var result = sforce.connection.create([logInfo]);
27             if (result[0].getBoolean("success")) { 
28                 //do success process
29             } else { 
30                 //do error process
31             }  
32         } 
33     </script>
34 </apex:page>

此种方式运行效果:

1.Log_Info__c最开始没有任何数据

2.访问当前页面

3.访问页面后数据库便存储了一条当前访问者访问的页面的Log数据

注意:此种方式对于谷歌浏览器会有一个问题,使用谷歌浏览器访问会出现Refused to set unsafe header "User-Agent",解决方式可以为下载connection.js注释掉关于User-Agent的处理,然后上传到static resources中,在VF page引入static resource而不是系统的connection.js即可

 总结:此种类似需求其实可以很多种方式实现,此处只是使用两种方式实现。第一种方式简单粗暴,而且兼容性好,第二种方式只是起到抛砖引玉的效果,关于ajax toolkit什么时候使用以及限制等请自行查看上方PDF。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信公众号:Java团长

一份超详细的Java问题排查工具单

平时的工作中经常碰到很多疑难问题的处理,在解决问题的同时,有一些工具起到了相当大的作用,在此书写下来,一是作为笔记,可以让自己后续忘记了可快速翻阅,二是分享,希...

731
来自专栏分享达人秀

ListView列表数据源——Adapter

在上一节一起了解了ListView的简单使用,那么本节继续来学习与ListView有着千丝万缕的Adapter。 一、了解MVC模式 在开始学习...

24010
来自专栏美团技术团队

Android漏洞扫描工具Code Arbiter

目前Android应用代码漏洞扫描工具种类繁多,效果良莠不齐,这些工具有一个共同的特点,都是在应用打包完成后对应用进行解包扫描。这种扫描有非常明显的缺点,扫描周...

52513
来自专栏IT开发技术与工作效率

VBA导入

1325
来自专栏贺贺的前端工程师之路

Angular2 之 单元测试

Angular的测试工具类包含了TestBed类和一些辅助函数方法,当时这不是唯一的,你可以不依赖Angular 的DI(依赖注入)系统,自己new出来测试类的...

712
来自专栏程序员的SOD蜜

常见.NET功能代码汇总 (2)

常见.NET功能代码汇总 23,获取和设置分级缓存 获取缓存:首先从本地缓存获取,如果没有,再去读取分布式缓存 写缓存:同时写本地缓存和分布式缓存 priv...

2326
来自专栏Seebug漏洞平台

TCTF/0CTF2018 XSS Writeup

刚刚4月过去的TCTF/0CTF2018一如既往的给了我们惊喜,其中最大的惊喜莫过于多道xss中Bypass CSP的题目,其中有很多应用于现代网站的防御思路。

7558
来自专栏实战docker

Java的wait()、notify()学习三部曲之二:修改JVM源码看参数

在上一章《 Java的wait()、notify()学习三部曲之一:JVM源码分析》中,我们通过JVM源码分析了线程同步的相关操作,但还是留下了一些疑惑未解:在...

2389
来自专栏Linyb极客之路

一份超详细的Java问题排查工具单

平时的工作中经常碰到很多疑难问题的处理,在解决问题的同时,有一些工具起到了相当大的作用,在此书写下来,一是作为笔记,可以让自己后续忘记了可快速翻阅,二是分享,希...

572
来自专栏IMWeb前端团队

ES6 + Babel + React低版本浏览器采坑记录

本文作者:IMWeb 何璇 原文出处:IMWeb社区 未经同意,禁止转载 有个项目要兼容IE8-10 某天,胆大的某前端开发由于业务需要升级了项目依赖...

3509

扫码关注云+社区