有的时候我们往往会遇到此种类似的需求:用户在访问某个详细的记录时,需要记录一下什么时候哪个用户访问过此页面,也就是说进入此页面时,需要插入一条记录到表中,表有用户信息,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. * 用于apex:page绑定的action,执行完构造函数以后执行此方法
  21. */
  22. public void createLog() {
  23. Log_Info__c log = new Log_Info__c();
  24. log.Access_Date__c = system.now();
  25. PageReference pr = ApexPages.currentPage();
  26. String relatedURL = pr.getUrl();
  27. Integer startIndex = relatedURL.lastIndexOf('/') + 1;
  28. Integer endIndex = relatedURL.indexOf('?') == -1 ? relatedURL.length() : relatedURL.indexOf('?');
  29. String pageName = relatedURL.substring(startIndex,endIndex);
  30. log.Access_Page__c = pageName;
  31. log.Accessor__c = UserInfo.getUserId();
  32. insert log;
  33. }
  34. }

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的引入

  1. <apex:page>
  2. <script src="../../soap/ajax/38.0/connection.js" type="text/javascript"></script>
  3. <script>
  4. sforce.connection.sessionId='{!GETSESSIONID()}';
  5. ...
  6. </script>
  7. ...
  8. </apex:page>

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

  1. <body>
  2. {!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。

salesforce 零基础学习(六十四)页面初始化时实现DML操作的更多相关文章

  1. salesforce 零基础学习(十六)Validation Rules & Date/time

    上一篇介绍的内容为Formula,其中的Date/time部分未指出,此篇主要介绍Date/time部分以及Validation rules. 本篇参考PDF: Date/time:https://r ...

  2. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  3. salesforce 零基础学习(十八)WorkFlow介绍及用法

    说起workflow大家肯定都不陌生,这里简单介绍一下salesforce中什么情况下使用workflow. 当你分配许多任务,定期发送电子邮件,记录修改时,可以通过自动配置workflow来完成以上 ...

  4. salesforce零基础学习(九十四)classic下pagelayout引入的vf page弹出内容更新此page layout

    我们在classic环境中,有时针对page layout不能实现的地方,可以引入 一个vf page去增强标准的 page layout 功能,有时可能要求这个 vf page的部分修改需要更新此 ...

  5. salesforce 零基础学习(六十八)http callout test class写法

    此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...

  6. salesforce零基础学习(八十九)使用 input type=file 以及RemoteAction方式上传附件

    在classic环境中,salesforce提供了<apex:inputFile>标签用来实现附件的上传以及内容获取.salesforce 零基础学习(二十四)解析csv格式内容中有类似的 ...

  7. salesforce 零基础学习(五十二)Trigger使用篇(二)

    第十七篇的Trigger用法为通过Handler方式实现Trigger的封装,此种好处是一个Handler对应一个sObject,使本该在Trigger中写的代码分到Handler中,代码更加清晰. ...

  8. salesforce零基础学习(八十)使用autoComplete 输入内容自动联想结果以及去重实现

    项目中,我们有时候会需要实现自动联想功能,比如我们想输入用户或者联系人名称,去联想出系统中有的相关的用户和联系人,当点击以后获取相关的邮箱或者其他信息等等.这种情况下可以使用jquery ui中的au ...

  9. salesforce零基础学习(九十六)Platform Event浅谈

    本篇参考:https://developer.salesforce.com/blogs/2018/07/which-streaming-event-do-i-use.html https://trai ...

随机推荐

  1. CDOJ 1269 ZhangYu Speech

    预处理打表,sum[i][j]表示1.....i这些数字中 j 有几个.然后就很好处理询问了. #include<stdio.h> #include<math.h> #incl ...

  2. 子序列和问题 acm

    题目描述 给定一个序列 {a1,a2,…,an},定义从a[l]到a[r]的连续子序列的和为sum[l,r],即sum[l,r]=sigma{ai},l<=i<=r.(1<=l< ...

  3. jquery中:input和input的区别分析

    :input表示选择表单中的input,select,textarea,button元素,input仅仅选择input元素. <html> <head> <style&g ...

  4. [iOS Animation]-CALayer 隐式动画

    隐式动画 按照我的意思去做,而不是我说的. -- 埃德娜,辛普森 我们在第一部分讨论了Core Animation除了动画之外可以做到的任何事情.但是动画是Core Animation库一个非常显著的 ...

  5. iOS开发者需要的5款排版工具

    Attributed String Creator Attributed String Creator可以从你的格式化文本中自动生成原生的Objective-C代码.你可以将文本写入.粘贴或者导入At ...

  6. iOS开发——绘图电池按百分比显示

    1.在DrawLine.h文件中提供了一个改变电池电量数值的接口 // //  DrawLine.h //  Demo-draw2 // //  Created by yyt on 16/5/11. ...

  7. 【转】一大波实用的 bash 别名和函数

    作为一个命令行探索者,你或许发现你自己一遍又一遍重复同样的命令.如果你总是用ssh进入到同一台电脑,如果你总是将一连串命令连接起来,如果你总是用同样的参数运行一个程序,你也许希望在这种不断的重复中为你 ...

  8. JDK8新特性面试

    java8:http://ifeve.com/java-8-features-tutorial/ 一.Lambda表达式和函数式接口 Lambda表达式(也叫做闭包) 它允许我们将一个函数当作方法的参 ...

  9. chkdsk

    通过 Microsoft 的相关帮助就可以明白,例如对D盘进行操作,则: 示例1:chkdsk /? 显示帮助信息. 示例2:chkdsk d: 检查D盘的磁盘状态,报告磁盘错误. 示例3:chkds ...

  10. Aaron Swartz – 互联网天才开挂的人生历程:每时每刻都问自己,现在这世界有什么最重要的事是我能参与去做的?

    Aaron说的一句话让我挺有感触的-- 相信你应该真的每时每刻都问自己,现在这世界有什么最重要的事是我能参与去做的? 如果你没在做那最重要的事,那又是为什么? 1986年11月8日,有个叫Aaron ...