SalesForce 查询 returns 在查询编辑器中产生结果,但在 Lightning 组件中的 APEX 代码中 returns 为空
SalesForce query returns results in Query Editor, but returns null from APEX code in Lightning component
我对 SalesForce 完全陌生,继承了一份不起作用的报告。请原谅任何不正确的术语,因为我正在学习这一切。该报告具有三个提示:状态、年份和成员。所有下拉菜单都应该填充 return 从 APEX class 中的函数编辑的数据。从选择列表中填充的状态和用循环填充的年份都可以正常工作。从 SQL 查询中填充的成员,return 什么都没有。如果我 运行 没有选择任何提示的报告(应该 return 来自 SQL 查询的未过滤结果列表),它也 return 什么都没有。当我在开发者控制台的查询编辑器中直接执行时,SQL 都查询 return 数据,但从 APEX 函数调用时,它们 return 什么也没有。
这是 Lightning 控制器的初始化代码:
doInit: function (component, event, helper) {
var action = component.get('c.getTrcAccounts');
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS' && component.isValid()) {
component.set('v.trcAccList', response.getReturnValue());
}
helper.getLocationState(component, event);
helper.getYear(component, event);
});
$A.enqueueAction(action);
},
这是该代码中引用的两个辅助函数:
getLocationState: function (component, event) {
var action = component.get('c.getLocationState');
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
component.set('v.LocationStateList', response.getReturnValue());
}
});
$A.enqueueAction(action);
},
getYear: function (component, event) {
var action = component.get('c.yearsOptions');
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
component.set('v.LocationYearList', response.getReturnValue());
}
});
$A.enqueueAction(action);
}
这是来自 APEX class 的代码,return 是这三个提示的数据:
Global class DataTableLocations {
@AuraEnabled
Global static List<TRC_Account__c> getTrcAccounts(){
set<string> trcAccountSet = new set<string>();
List<TRC_Account__c> traccList = new List<TRC_Account__c>();
for(TRC_Account__c trcacc : [SELECT Id, Name from TRC_Account__c WHERE TRC_Member__c = True order by Name limit 50000]){
if(!trcAccountSet.contains(trcacc.Name)){
trcAccountSet.add(trcacc.Name);
traccList.add(trcacc);
}
}
if(traccList.size()>0){
return traccList;
}
else{
return null;
}
}
@AuraEnabled
Global static List<string> getLocationState(){
List<string> options = new List<string>();
//options.add(new SelectOption('SelectAll', 'Select All'));
for( Schema.PicklistEntry f : Location__c.Physical_Address_State__c.getDescribe().getPicklistValues()) {
options.add(f.getValue());
}
return options;
}
@AuraEnabled
Global static List<string> yearsOptions() {
List<string> options = new List<string>();
date OldDate= date.today().addYears(-18);
integer oldyear=OldDate.year();
for( integer i=0; i<19 ;i++) {
options.add(string.valueOf(oldyear));
oldyear++;
}
return options;
}
}
If I 运行 SELECT Id, Name from TRC_Account__c WHERE TRC_Member__c = True order by Name limit 50000 直接在query editor window中开发人员控制台,我得到 7 个结果。但是,如果我在 doInit 函数中为 getTrcAccounts 输出 response.getReturnValue(),则它为空。
非常感谢您的帮助,因为我们正处于 c运行ch 网站重新设计的一段时间。有人告诉我这些报告曾在某一时刻起作用,但没有人知道它们何时停止起作用,而且我们从另一家进行原始开发的公司那里继承了这段代码。谢谢!
更新:
如果有帮助,这是我认为在 public 页面上使用的 lightning 应用程序中的代码:
<aura:application extends="ltng:outApp" access="GLOBAL" implements="ltng:allowGuestAccess">
<aura:dependency resource="c:SearchBinReceiptsByYear"/>
</aura:application>
编辑
是的,这是一个 public 页面,名为“Salesforce 站点”。它无需登录即可向全世界公开。这些具有特殊的安全性,因为大多数时候您不想公开这样的数据。充其量你会显示联系我们的表格,也许是一些要下载的文件,产品目录......这一切都非常锁定,默认是禁止一切,然后管理员决定允许什么。拥有 Visualforce 页面 + Aura 组件有点不寻常,但没关系,它发生了。
如果您从 salesforce 内部访问此页面,您(和任何其他内部用户)可以看到结果。 https://mydomain.my.salesforce.com/apex/SearchBinReceiptsByYear 之类的内容,对于您来说,该页面将正常工作,“只是”不在 salesforce 之外。
当像那样暴露在网络上时 - 没有登录用户。有特殊的“[Site Name] Guest User”,如果您在“设置”中搜索“站点”,就可以看到它们。它有一个特殊的配置文件,其中也有 [Site Name]。令人讨厌的是 - 它没有显示在用户或配置文件列表中。
当 Salesforce(自动)激活关键更新时,您的代码中断。大概是这个:https://releasenotes.docs.salesforce.com/en-us/spring20/release-notes/rn_networks_secure_perms_guests.htm There are some good resources on the net if you Google "Secure Object Permissions for Guest Users", for example https://katiekodes.com/salesforce-spring-20-guest-user/
询问您的系统管理员同事或阅读一些关于 sharing rules 的内容。
您必须转到“设置”->“共享规则”。有一个复选框导致您的东西损坏,您无法取消选中它。
向下滚动到您的 TRC 帐户对象并点击“新建”。您需要创建类似这样的内容,但要符合您的条件(TRC 成员等于 true)
保存,稍等(重新计算分享可能需要一段时间,您会收到一封电子邮件)并尝试页面。
如果它仍然不起作用,您必须检查来宾用户的个人资料,它可能需要读取 TRC 帐户及其名称字段的权限。
如果是 Salesforce 站点 - 试试这个来找到它:https://help.salesforce.com/articleView?id=000334554&type=1&mode=1
如果它是客户门户、社区、数字体验(他们多次重命名产品)- 尝试 https://help.salesforce.com/articleView?id=sf.rss_config_guest_user_profile.htm&type=5
原回答
看起来 运行 没问题,因为首先获取帐户(成员?),在该获取的回调(数据从服务器返回时要做什么)中,您有 helper.getLocationState
,helper.getYear
。你写道,这些填充确定。这不是最佳性能代码,但应该可以完成工作。
无特定顺序...
对于系统管理员来说,整个过程是否正常?还是每个人都坏了?如果它适用于系统管理员,它可能与共享有关,您的系统管理员应该知道(设置 - >共享设置是您控制谁可以看到什么的地方。也许“凡人”不允许看到任何数据?通常系统管理员会绕过它。作为一个快速而肮脏的测试,您可以将 class 定义修改为 global without sharing class DataTableLocations
,但这是一个非常丑陋的 hack。
如果您在 运行 安装此组件时打开 DeveloperConsole(右上角)会发生什么情况,您是否在日志中看到任何错误?如果在控制台中你去 Debug -> Open ExecuteAnonymous 和 运行 这段代码会发生什么:
System.debug(DataTableLocations.getTrcAccounts());
它 return 有什么用吗?抛出错误?
您可以转到设置 -> 调试模式,勾选您的用户旁边的复选框并保存。这会稍微降低系统速度,但可以让您更好地调试 javascript。然后,您可以在源代码中添加一些 debugger;
或 console.log
语句,并查看浏览器控制台中发生的情况(Ctrl+Shift+J 在 Chrome 中,Ctrl+Shift+I 在 firefox 中) .例如
action.setCallback(this, function (response) {
var state = response.getState();
debugger;
console.log(state);
console.log(component.isValid());
console.table(response.getReturnValue());
if (state === 'SUCCESS' && component.isValid()) {
component.set('v.trcAccList', response.getReturnValue());
}
console.log(component.get('v.trcAccList'));
debugger;
helper.getLocationState(component, event);
helper.getYear(component, event);
});
在类似 HTML 的文件中,“cmp”文件中实际使用的 trcAccList
变量如何?可能设置没问题,有7条记录,但是显示不对?
我对 SalesForce 完全陌生,继承了一份不起作用的报告。请原谅任何不正确的术语,因为我正在学习这一切。该报告具有三个提示:状态、年份和成员。所有下拉菜单都应该填充 return 从 APEX class 中的函数编辑的数据。从选择列表中填充的状态和用循环填充的年份都可以正常工作。从 SQL 查询中填充的成员,return 什么都没有。如果我 运行 没有选择任何提示的报告(应该 return 来自 SQL 查询的未过滤结果列表),它也 return 什么都没有。当我在开发者控制台的查询编辑器中直接执行时,SQL 都查询 return 数据,但从 APEX 函数调用时,它们 return 什么也没有。
这是 Lightning 控制器的初始化代码:
doInit: function (component, event, helper) {
var action = component.get('c.getTrcAccounts');
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS' && component.isValid()) {
component.set('v.trcAccList', response.getReturnValue());
}
helper.getLocationState(component, event);
helper.getYear(component, event);
});
$A.enqueueAction(action);
},
这是该代码中引用的两个辅助函数:
getLocationState: function (component, event) {
var action = component.get('c.getLocationState');
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
component.set('v.LocationStateList', response.getReturnValue());
}
});
$A.enqueueAction(action);
},
getYear: function (component, event) {
var action = component.get('c.yearsOptions');
action.setCallback(this, function (response) {
var state = response.getState();
if (state === 'SUCCESS') {
component.set('v.LocationYearList', response.getReturnValue());
}
});
$A.enqueueAction(action);
}
这是来自 APEX class 的代码,return 是这三个提示的数据:
Global class DataTableLocations {
@AuraEnabled
Global static List<TRC_Account__c> getTrcAccounts(){
set<string> trcAccountSet = new set<string>();
List<TRC_Account__c> traccList = new List<TRC_Account__c>();
for(TRC_Account__c trcacc : [SELECT Id, Name from TRC_Account__c WHERE TRC_Member__c = True order by Name limit 50000]){
if(!trcAccountSet.contains(trcacc.Name)){
trcAccountSet.add(trcacc.Name);
traccList.add(trcacc);
}
}
if(traccList.size()>0){
return traccList;
}
else{
return null;
}
}
@AuraEnabled
Global static List<string> getLocationState(){
List<string> options = new List<string>();
//options.add(new SelectOption('SelectAll', 'Select All'));
for( Schema.PicklistEntry f : Location__c.Physical_Address_State__c.getDescribe().getPicklistValues()) {
options.add(f.getValue());
}
return options;
}
@AuraEnabled
Global static List<string> yearsOptions() {
List<string> options = new List<string>();
date OldDate= date.today().addYears(-18);
integer oldyear=OldDate.year();
for( integer i=0; i<19 ;i++) {
options.add(string.valueOf(oldyear));
oldyear++;
}
return options;
}
}
If I 运行 SELECT Id, Name from TRC_Account__c WHERE TRC_Member__c = True order by Name limit 50000 直接在query editor window中开发人员控制台,我得到 7 个结果。但是,如果我在 doInit 函数中为 getTrcAccounts 输出 response.getReturnValue(),则它为空。
非常感谢您的帮助,因为我们正处于 c运行ch 网站重新设计的一段时间。有人告诉我这些报告曾在某一时刻起作用,但没有人知道它们何时停止起作用,而且我们从另一家进行原始开发的公司那里继承了这段代码。谢谢!
更新:
如果有帮助,这是我认为在 public 页面上使用的 lightning 应用程序中的代码:
<aura:application extends="ltng:outApp" access="GLOBAL" implements="ltng:allowGuestAccess">
<aura:dependency resource="c:SearchBinReceiptsByYear"/>
</aura:application>
编辑
是的,这是一个 public 页面,名为“Salesforce 站点”。它无需登录即可向全世界公开。这些具有特殊的安全性,因为大多数时候您不想公开这样的数据。充其量你会显示联系我们的表格,也许是一些要下载的文件,产品目录......这一切都非常锁定,默认是禁止一切,然后管理员决定允许什么。拥有 Visualforce 页面 + Aura 组件有点不寻常,但没关系,它发生了。
如果您从 salesforce 内部访问此页面,您(和任何其他内部用户)可以看到结果。 https://mydomain.my.salesforce.com/apex/SearchBinReceiptsByYear 之类的内容,对于您来说,该页面将正常工作,“只是”不在 salesforce 之外。
当像那样暴露在网络上时 - 没有登录用户。有特殊的“[Site Name] Guest User”,如果您在“设置”中搜索“站点”,就可以看到它们。它有一个特殊的配置文件,其中也有 [Site Name]。令人讨厌的是 - 它没有显示在用户或配置文件列表中。
当 Salesforce(自动)激活关键更新时,您的代码中断。大概是这个:https://releasenotes.docs.salesforce.com/en-us/spring20/release-notes/rn_networks_secure_perms_guests.htm There are some good resources on the net if you Google "Secure Object Permissions for Guest Users", for example https://katiekodes.com/salesforce-spring-20-guest-user/
询问您的系统管理员同事或阅读一些关于 sharing rules 的内容。
您必须转到“设置”->“共享规则”。有一个复选框导致您的东西损坏,您无法取消选中它。
向下滚动到您的 TRC 帐户对象并点击“新建”。您需要创建类似这样的内容,但要符合您的条件(TRC 成员等于 true)
保存,稍等(重新计算分享可能需要一段时间,您会收到一封电子邮件)并尝试页面。
如果它仍然不起作用,您必须检查来宾用户的个人资料,它可能需要读取 TRC 帐户及其名称字段的权限。
如果是 Salesforce 站点 - 试试这个来找到它:https://help.salesforce.com/articleView?id=000334554&type=1&mode=1
如果它是客户门户、社区、数字体验(他们多次重命名产品)- 尝试 https://help.salesforce.com/articleView?id=sf.rss_config_guest_user_profile.htm&type=5
原回答
看起来 运行 没问题,因为首先获取帐户(成员?),在该获取的回调(数据从服务器返回时要做什么)中,您有 helper.getLocationState
,helper.getYear
。你写道,这些填充确定。这不是最佳性能代码,但应该可以完成工作。
无特定顺序...
对于系统管理员来说,整个过程是否正常?还是每个人都坏了?如果它适用于系统管理员,它可能与共享有关,您的系统管理员应该知道(设置 - >共享设置是您控制谁可以看到什么的地方。也许“凡人”不允许看到任何数据?通常系统管理员会绕过它。作为一个快速而肮脏的测试,您可以将 class 定义修改为 global without sharing class DataTableLocations
,但这是一个非常丑陋的 hack。
如果您在 运行 安装此组件时打开 DeveloperConsole(右上角)会发生什么情况,您是否在日志中看到任何错误?如果在控制台中你去 Debug -> Open ExecuteAnonymous 和 运行 这段代码会发生什么:
System.debug(DataTableLocations.getTrcAccounts());
它 return 有什么用吗?抛出错误?
您可以转到设置 -> 调试模式,勾选您的用户旁边的复选框并保存。这会稍微降低系统速度,但可以让您更好地调试 javascript。然后,您可以在源代码中添加一些 debugger;
或 console.log
语句,并查看浏览器控制台中发生的情况(Ctrl+Shift+J 在 Chrome 中,Ctrl+Shift+I 在 firefox 中) .例如
action.setCallback(this, function (response) {
var state = response.getState();
debugger;
console.log(state);
console.log(component.isValid());
console.table(response.getReturnValue());
if (state === 'SUCCESS' && component.isValid()) {
component.set('v.trcAccList', response.getReturnValue());
}
console.log(component.get('v.trcAccList'));
debugger;
helper.getLocationState(component, event);
helper.getYear(component, event);
});
在类似 HTML 的文件中,“cmp”文件中实际使用的 trcAccList
变量如何?可能设置没问题,有7条记录,但是显示不对?