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。
作者:zero
博客地址:http://www.cnblogs.com/zero-zyq/
本文欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接
如果文章的内容对你有帮助,欢迎点赞~
为方便手机端查看博客,现正在将博客迁移至微信公众号:Salesforce零基础学习,欢迎各位关注。