检索数组JS中的所有对象
retrieving all objects in an array JS
我在 ServiceNow 工作并尝试建立一个数组来检索与用户相关的所有知识文章。我下面的代码只返回其中一篇文章,我不确定为什么...有什么建议吗?
var kaArray = [];
var ka = new GlideRecord('my_knowledge');
ka.addQuery('workflow_state', 'Published');
ka.addQuery('kb_category.label', 'Benefits');
ka.addQuery('occ_series', 'CONTAINS', occ)
.addOrCondition('location', 'CONTAINS', loc)
.addOrCondition(
ka.addNullQuery('location') && ka.addNullQuery('occ_series')
);
ka.orderByDesc('sys_updated_on');
ka.query();
while(ka.next()) {
obj = {number: ka.number.toString(),
short_desc: ka.short_description.toString(),
url: 'kb_view.do?sysparm_article=' + ka.number};
kaArray.push(obj);
}
有几项我会推荐,其中之一可能是您问题的解决方案。
您正在使用条件运算符“&&”来...好吧,恐怕我不太确定。您不能按照您尝试的方式在 JavaScript 中执行此操作。此外,由于 .addOrCondition()
不是 return 您想用作 bool 的值),这将不起作用。相反,只需将下一个命令放在下一行。我将在底部向您展示代码的完成版本。
而不是这些复杂的 .addNullQuery()
、addQuery()
和 .addOrCondition() 调用序列,只需导航到您对过滤感兴趣的 table ,并在条件生成器中从字面上构建过滤器。然后,右键单击 final 筛选面包屑,然后单击 "copy query",然后使用 .addEncodedQuery()
。像这样:
gr.addEncodedQuery('short_descriptionLIKEeclipse^kb_category=c78a2d2047b002007f47563dbb9a71bf^workflow_state=published' /点击结果"copy query"/);
为什么要使用范围应用和自定义 table?如果您打算在市场上列出范围内的应用程序,它是有意义的,但基于 table 名称,它听起来像是针对特定业务的。如果有的话,我推荐一个全球应用程序。我还非常强烈地建议,无论是范围内的还是全球性的,您只需创建一个新的知识库而不是创建一个全新的 table,除非您在此 KB 上拥有一些您需要的高级功能并且愿意牺牲一个伟大的处理 OOB 功能以获取它。并不是说你在做什么是错的,只是想确保你意识到你可能会给自己带来的麻烦。 :-)
据我所知,使用您当前的配置,您不必担心 JavaScript 的传递引用特性,我看不到您在任何地方声明 "obj"。你可能想这样做,并给它一个更好的名字。不过,您可能希望将该对象添加到数组中的功能化。如果#5 不正确,那么问题很可能是由于我错过了传递参考问题,至少这是我的猜测。我可以看到您在 while 循环内的第三行至少有一个 pass-by-ref 问题:
url: 'kb_view.do?sysparm_article=' + ka.number};
总是 使用"getters and setters"。也就是说,当你想要一个 GlideRecord 的值时,永远不要直接引用 gr.fieldName
。相反,使用 gr.getValue('fieldName');
。作为一种选择(我不喜欢但没有合理的理由不这样做),您也可以像在其他几个地方一样使用 .toString()
。这显式地将值转换为字符串而不是它本身的对象(GlideElement 对象)。我不太喜欢这样,因为这意味着您要将 OBJECT 强制转换为 STRING。没有简单的方法可以做到这一点,因此它依赖于 GlideElement class 的内置方法来覆盖大多数其他类型的 .toString 方法。
- 我敢打赌这个查询,不管怎样,它的编写方式,return只有一条记录。您可以在查询后使用
gs.info('Looking through ' + ka.getRowCount() + ' records.');
之类的内容轻松地对此进行测试。
对于你,我虚心推荐《Learning ServiceNow》。完全公开,这是我自己的书。也就是说,我专门为那些知识和经验水平与您完全相同的人量身定制了这本书,我认为您会从中受益匪浅。大多数 SN 开发者会从中获益良多,但我认为您处于一个特殊的位置,可以充分利用它。
我知道它说的是 6 月 9 日,但这应该会在本月底或之后的几天内发布。
这是我认为您正在尝试执行的操作的一个版本,它应该有效。我确信查询需要稍微调整一下——我不得不猜测你要做什么,但我认为 ^NQ 的使用最接近你想要完成的事情。就像我说的,只需在 table 上构建您的查询,然后将其复制到 encQuery(并替换我现有的 logic/return 来自 buildEncQuery 的正确查询)。
这是:
/**
* encQuery will hold the temporary and final encoded query strings, which will look something like this (when finished):
* "workflow_state=published^kb_category.label=Benefits^federal_occ_seriesLIKEOCC_HERE^ORlocationLIKELOC_HERE^NQworkflow_state=published^kb_category.label=Benefits^locationISEMPTY^federal_occ_seriesISEMPTY"
* @type {String}
*/
var encQuery = buildEncQuery(occ, loc); //occ and loc were used in your original queries, so I assume they're variables that are available to you in this scope at this point in your script.
/**
* An array of objects, each containing data about knowledge articles returned from our query using encQuery.
* @type {{name: string, short_desc: string, url: string}[]}
*/
var knowledgeArray = [];
/**
* The GR we're iterating over
* @type {GlideRecord}
*/
var knowledgeGR = new GlideRecord('x_81991_federal_hc_federal_knowledge');
knowledgeGR.addEncodedQuery(encQuery);
knowledgeGR.orderByDesc('sys_updated_on');
knowledgeGR.query();
while (knowledgeGR.next()) {
knowledgeArray.push({
number: knowledgeGR.getValue('number'),
short_desc: knowledgeGR.getValue('short_description'),
url: 'kb_view.do?sysparm_article=' + knowledgeGR.getValue('number')
});
}
gs.info('Located ' + knowledgeGR.getRowCount() + ' records. Array length: ' + knowledgeArray.length + '.');
//Done
/**
* Builds the encoded query for the calling function.
* @param occ {*}
* @param loc {*}
* @returns {string}
*/
function buildEncQuery(occ, loc) {
if (occ === undefined || loc === undefined) {
return;
}
var encQuery = 'workflow_state=published^kb_category.label=Benefits'
encQuery += '^federal_occ_seriesLIKE' + occ + '^ORlocationLIKE' + loc + '^NQ' + encQuery + '^locationISEMPTY^federal_occ_seriesISEMPTY';
return encQuery;
}
编辑:我注意到您经常在 Whosebug 上发帖。但是,您似乎并没有将问题标记为已回答。我建议您这样做,但我也建议您查看 sndevs.slack.com。这是一个由其他 ServiceNow 开发人员组成的很棒的社区。
我在 ServiceNow 工作并尝试建立一个数组来检索与用户相关的所有知识文章。我下面的代码只返回其中一篇文章,我不确定为什么...有什么建议吗?
var kaArray = [];
var ka = new GlideRecord('my_knowledge');
ka.addQuery('workflow_state', 'Published');
ka.addQuery('kb_category.label', 'Benefits');
ka.addQuery('occ_series', 'CONTAINS', occ)
.addOrCondition('location', 'CONTAINS', loc)
.addOrCondition(
ka.addNullQuery('location') && ka.addNullQuery('occ_series')
);
ka.orderByDesc('sys_updated_on');
ka.query();
while(ka.next()) {
obj = {number: ka.number.toString(),
short_desc: ka.short_description.toString(),
url: 'kb_view.do?sysparm_article=' + ka.number};
kaArray.push(obj);
}
有几项我会推荐,其中之一可能是您问题的解决方案。
您正在使用条件运算符“&&”来...好吧,恐怕我不太确定。您不能按照您尝试的方式在 JavaScript 中执行此操作。此外,由于
.addOrCondition()
不是 return 您想用作 bool 的值),这将不起作用。相反,只需将下一个命令放在下一行。我将在底部向您展示代码的完成版本。而不是这些复杂的
.addNullQuery()
、addQuery()
和 .addOrCondition() 调用序列,只需导航到您对过滤感兴趣的 table ,并在条件生成器中从字面上构建过滤器。然后,右键单击 final 筛选面包屑,然后单击 "copy query",然后使用.addEncodedQuery()
。像这样:
为什么要使用范围应用和自定义 table?如果您打算在市场上列出范围内的应用程序,它是有意义的,但基于 table 名称,它听起来像是针对特定业务的。如果有的话,我推荐一个全球应用程序。我还非常强烈地建议,无论是范围内的还是全球性的,您只需创建一个新的知识库而不是创建一个全新的 table,除非您在此 KB 上拥有一些您需要的高级功能并且愿意牺牲一个伟大的处理 OOB 功能以获取它。并不是说你在做什么是错的,只是想确保你意识到你可能会给自己带来的麻烦。 :-)
据我所知,使用您当前的配置,您不必担心 JavaScript 的传递引用特性,我看不到您在任何地方声明 "obj"。你可能想这样做,并给它一个更好的名字。不过,您可能希望将该对象添加到数组中的功能化。如果#5 不正确,那么问题很可能是由于我错过了传递参考问题,至少这是我的猜测。我可以看到您在 while 循环内的第三行至少有一个 pass-by-ref 问题:
url: 'kb_view.do?sysparm_article=' + ka.number};
总是 使用"getters and setters"。也就是说,当你想要一个 GlideRecord 的值时,永远不要直接引用 gr.fieldName
。相反,使用 gr.getValue('fieldName');
。作为一种选择(我不喜欢但没有合理的理由不这样做),您也可以像在其他几个地方一样使用 .toString()
。这显式地将值转换为字符串而不是它本身的对象(GlideElement 对象)。我不太喜欢这样,因为这意味着您要将 OBJECT 强制转换为 STRING。没有简单的方法可以做到这一点,因此它依赖于 GlideElement class 的内置方法来覆盖大多数其他类型的 .toString 方法。
- 我敢打赌这个查询,不管怎样,它的编写方式,return只有一条记录。您可以在查询后使用
gs.info('Looking through ' + ka.getRowCount() + ' records.');
之类的内容轻松地对此进行测试。
对于你,我虚心推荐《Learning ServiceNow》。完全公开,这是我自己的书。也就是说,我专门为那些知识和经验水平与您完全相同的人量身定制了这本书,我认为您会从中受益匪浅。大多数 SN 开发者会从中获益良多,但我认为您处于一个特殊的位置,可以充分利用它。 我知道它说的是 6 月 9 日,但这应该会在本月底或之后的几天内发布。
这是我认为您正在尝试执行的操作的一个版本,它应该有效。我确信查询需要稍微调整一下——我不得不猜测你要做什么,但我认为 ^NQ 的使用最接近你想要完成的事情。就像我说的,只需在 table 上构建您的查询,然后将其复制到 encQuery(并替换我现有的 logic/return 来自 buildEncQuery 的正确查询)。 这是:
/**
* encQuery will hold the temporary and final encoded query strings, which will look something like this (when finished):
* "workflow_state=published^kb_category.label=Benefits^federal_occ_seriesLIKEOCC_HERE^ORlocationLIKELOC_HERE^NQworkflow_state=published^kb_category.label=Benefits^locationISEMPTY^federal_occ_seriesISEMPTY"
* @type {String}
*/
var encQuery = buildEncQuery(occ, loc); //occ and loc were used in your original queries, so I assume they're variables that are available to you in this scope at this point in your script.
/**
* An array of objects, each containing data about knowledge articles returned from our query using encQuery.
* @type {{name: string, short_desc: string, url: string}[]}
*/
var knowledgeArray = [];
/**
* The GR we're iterating over
* @type {GlideRecord}
*/
var knowledgeGR = new GlideRecord('x_81991_federal_hc_federal_knowledge');
knowledgeGR.addEncodedQuery(encQuery);
knowledgeGR.orderByDesc('sys_updated_on');
knowledgeGR.query();
while (knowledgeGR.next()) {
knowledgeArray.push({
number: knowledgeGR.getValue('number'),
short_desc: knowledgeGR.getValue('short_description'),
url: 'kb_view.do?sysparm_article=' + knowledgeGR.getValue('number')
});
}
gs.info('Located ' + knowledgeGR.getRowCount() + ' records. Array length: ' + knowledgeArray.length + '.');
//Done
/**
* Builds the encoded query for the calling function.
* @param occ {*}
* @param loc {*}
* @returns {string}
*/
function buildEncQuery(occ, loc) {
if (occ === undefined || loc === undefined) {
return;
}
var encQuery = 'workflow_state=published^kb_category.label=Benefits'
encQuery += '^federal_occ_seriesLIKE' + occ + '^ORlocationLIKE' + loc + '^NQ' + encQuery + '^locationISEMPTY^federal_occ_seriesISEMPTY';
return encQuery;
}
编辑:我注意到您经常在 Whosebug 上发帖。但是,您似乎并没有将问题标记为已回答。我建议您这样做,但我也建议您查看 sndevs.slack.com。这是一个由其他 ServiceNow 开发人员组成的很棒的社区。