问题描述
因此,我首先要说我是一位具有丰富经验的C#.Net / Java开发人员,但是我在Salesforce方面的经验为零。从来没有见过今天。因此,另一个团队要求我向“联系人”对象添加一个自定义按钮,单击该对象将调用一个外部API,并使用响应更新“联系人”中的一个自定义字段。它的意思是“只要编写一个单击按钮时就会调用API的Javascript,它实际上就嵌入到页面中,只需15分钟的工作...”。
在看起来很过时的文档之后,我进入了对象管理器,选择了Contact对象,然后进入了Buttons,Links和Actions页面。我假设在使用Execute Javascript行为完成此操作之前,建议不要使用Lightning版本。因此,经过大量的Google搜索之后,我已经阅读了有关APEX类,Visualforce组件,Lightning组件,Salesforce REST API等的信息。这不是15分钟的工作。
基本上,要求是在此“联系人”页面中嵌入一个按钮(或操作或..?),以便当销售人员单击该按钮时,它会收集联系人的一些详细信息,并使用它们来构成对外部服务。数据将用于形成响应,然后必须将其读取(作为JSON,然后进行解析)并写入Contact的自定义字段中。
开发解决方案的最佳方法是什么?在Apex调试环境中,我将代码组合在一起以调用API并解析JSON响应,我假设需要使用一种调用此代码并返回响应的方法将其包装在Apex类中。我不确定如何从按钮中调用它,以及如何更新“联系人”中的字段。 我需要通过Apex Class方法执行所有操作吗?传递对联系人的引用,或者是否需要另一个组件介于两者之间并执行此操作。 我是否可以假设我需要使用Salesforce API更新联系人?
任何指针表示赞赏。
解决方法
我会写信给我
记录页面/页面布局上的按钮->照明组件或流->用于收集数据的Apex类->顶点类请求和响应API(不要忘记将端点添加到远程站点设置)->解析响应并更新联系人(您可以在Apex中使用查询和DML操作)
照明组件将非常简单,只需要一个顶点类作为控制器示例
<aura:component implements="force:appHostable,lightning:isUrlAddressable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" controller="contactController" access="global" >
<aura:handler name="init" value="{!this}" action="{!c.fetchContact}"/>
</aura:component>
控制器
({
fetchContact : function(component,event,helper) {
helper.fetchContactHelper(component,helper);
}
})
助手
({
fetchAccHelper : function(component,helper) {
var action = component.get("c.fetchContacts");
action.setParams({
});
action.setCallback(this,function(response){
var state = response.getState();
if (state === "SUCCESS") {
}
});
$A.enqueueAction(action);
}
})
假设顶点函数是fetchContacts和class contactController
,哦,天哪。这可能是15分钟的工作,但是绝对“很容易”,或者有一些例子;)
- 您的用户界面是“经典”还是“闪电”?他们有计划很快迁移到Lightning吗?如果您认为“ Execute JavaScript”黑客通过了,那我就算是闪电。
- 您是否关心按钮/动作在哪里?右上角的其他所有按钮都还不错吗?还是您希望它可以拖放到页面中的几乎任何区域?
- API标注是否需要用户名,密码或证书?它将确定您是否只需要将防火墙上的终结点列入白名单(设置->远程站点设置),或者是否需要更高级的设置(设置->命名凭据)。
- 您是否已确定要安装一些工具的SFDX命令行(CLI),VSCode /? Lightning Web Components是最先进的,最时尚的,但是您不能直接在浏览器中创建它们(至少现在还没有),需要工具。 Visualforce可以,但是对于这种用例来说没有什么特别的,Aura组件编写起来有些笨拙-但您可以在开发人员控制台中完成这两项工作而无需额外的工具。
- 解析JSON响应-取决于它的复杂程度,您可以使用
JSON.deserializeUntyped()
来手工制作解析器,但是生命太短了。这是一个不错的apex代码生成器,类似于您从解析WSDL中获得的代码:https://json2apex.herokuapp.com/
我们将尝试做Aura组件方式。丑陋,LWC是未来,但嘿,它会让您入门。
转到设置->远程站点设置,然后使用https://en.wikipedia.org/
添加新条目
创建新的Apex类:
public with sharing class Stack63364119 {
static final String endpoint = 'https://en.wikipedia.org/w/api.php?action=query&format=json&list=search&srsearch=';
@AuraEnabled
public static String doCallout(Id contactId){
if(contactId == null){
throw new MyException('Missing record id');
}
List<Contact> contacts = [SELECT MailingCountry FROM Contact WHERE Id = :contactId];
if(contacts.isEmpty() || String.isBlank(contacts[0].MailingCountry)){
throw new MyException('Could not find the contact');
}
Contact c = contacts[0];
HttpRequest req = new HttpRequest();
req.setEndpoint(endpoint + c.MailingCountry);
req.setMethod('GET');
HTTPResponse res = new Http().send(req);
System.debug(res.getStatus());
System.debug(res.getBody());
// no special parsing,just chuck it into Description field
// no error handling
if(res.getStatusCode() == 200){
c.Description = res.getBody().abbreviate(32000);
update c;
}
return res.getBody();
}
public class MyException extends Exception{}
}
在开发人员控制台中制作新的“ Lighning Component”(它将是Aura,而不是LWC)。您可以勾选有关“闪电快速行动”的最后一个复选框。名称可以与类相同,但不必相同。
对于组件(〜html部分)粘贴
<!-- Loosely based on https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/controllers_server_actions_call.htm -->
<aura:component controller="Stack63364119" implements="force:hasRecordId,force:lightningQuickAction" >
<!-- in the name of all that is holy do not name the JS function same as the Apex class function,it'll give you very cryptic errors to debug -->
<aura:handler name="init" value="{!this}" action="{!c.runCallout}"/>
</aura:component>
对于控制器(〜JavaScript)粘贴
({
runCallout : function(cmp) {
let action = cmp.get('c.doCallout');
action.setParams({contactId : cmp.get('v.recordId')});
action.setCallback(this,function(response){
let state = response.getState();
if (state === "SUCCESS") {
alert('Saved OK: ' + response.getReturnValue());
$A.get("e.force:closeQuickAction").fire(); // if you want to self-close
} else if (state === "ERROR") {
var errors = response.getError();
if (errors) {
if (errors[0] && errors[0].message) {
console.log("Error message: " + errors[0].message);
}
} else {
console.log("Unknown error");
}
}
});
$A.enqueueAction(action);
}
})
最后进入对象管理器->联系人->按钮链接和操作。创建新的快速操作。 并将其添加到页面布局!
它应该使您入门。也许您会决定对其进行拆分,Apex只会执行标注,将结果返回到UI,如果用户满意,则可以使用以下任一方法来更新联系人:https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/data_service_save_record.htm。别担心(但是用户单击两次会感到满意)。
P.S。如果您对其进行调整并且死了,但是很难看到任何JavaScript错误-这是因为默认值是在发布模式下运行,SF稍微重写了源代码,优化了代码,并为IE11之类的“浏览器”添加了polyfill。设置->调试模式并为您的用户启用。
P.P.S。在沙盒/开发组织中,最好去设置->会话设置->并取消选中“启用安全和持久的浏览器缓存以提高性能”。您的组件将始终保持新鲜,并节省一些按Ctrl + R的速度。不要在产品中这样做;)