I want to iterate over an array checking if a node has lower nodes and if the node is compatible with the user's role.
我想迭代一个数组,检查一个节点是否有较低的节点,以及该节点是否与用户的角色兼容。
I thought I might use the "for (let entry of someArray)" to obtain each value of node in the array however the "someArray" is the return value of a function:
我以为我可能会使用“for(让someArray的输入)”获取数组中节点的每个值,但“someArray”是函数的返回值:
public menuList(): any {
return [
// SCHEDULER
{
route: ["", "scheduler"],
name: "scheduler",
moduleId: PLATFORM.moduleName("../components/scheduler/scheduler"),
title: "scheduler",
nav: true,
settings: {
icon: "user",
roles: ["Employee", "Admin"],
pos: "left"
}
},
// CLIENTS
{
route: "clients",
name: "clients",
moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"),
title: "Clients",
nav: true,
settings: {
icon: "user",
roles: ["Employee", "Admin"],
pos: "left",
nav: [
{
route: "clients/ClientsList",
name: "clientList",
moduleId: PLATFORM.moduleName("../components/clients/clientList/clientList"),
href: "#clients/clientsList",
title: "Client List",
settings: {
icon: "list",
roles: ["Employee", "Admin"],
}
},
{
settings: {
roles: ["Employee", "Admin"],
divider: true,
}
},
{
route: "clients/create",
name: "newClient",
moduleId: PLATFORM.moduleName("../components/clients/newClient/newClient"),
href: "#clients/Create",
title: "Create Client",
settings: {
icon: "user",
roles: ["Employee", "Admin"],
}
}
]
}
},
// JOBS
{
route: "jobs",
name: "jobs",
moduleId: PLATFORM.moduleName("../components/jobs/jobsList"),
title: "Jobs",
nav: true,
settings: {
icon: "list",
roles: ["Employee", "Admin"],
pos: "left"
},
},
// ACCOUNTING
// Accounting - 1st level route WITH SUBROUTES
{
route: "accounting",
name: "accounting",
moduleId: PLATFORM.moduleName("../components/accounting/ledgerEnquiry/ledgerEnquiry"),
title: "Accounting",
nav: true,
settings: {
icon: "usd",
roles: ["Employee", "Admin"],
pos: "left",
nav: [
{
title: "Creditor Cost Invoices",
icon: "tasks",
nav: true,
roles: ["Employee", "Admin"],
settings: {
nav: [
{
title: 'Creditor Payments',
icon: 'usd',
roles: ["Employee", "Admin"],
settings: {
nav: [
{
route: "accounting/creditorCostInvoices/payments/paymentsRegister",
name: "paymentsRegister",
moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/paymentsRegister/paymentsRegister"),
href: '#accounting/creditorCostInvoices/payments/paymentsRegister',
title: 'Payments Register',
settings: {
icon: 'list',
roles: ["Employee", "Admin"]
}
},
{
settings: {
roles: ["Employee", "Admin"],
divider: true,
}
},
{
route: "accounting/creditorCostInvoices/payments/creditorPromptPayments",
name: "promptPayments",
moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/creditorPromptPayments/creditorPromptPayments"),
href: '#accounting/creditorCostInvoices/payments/creditorPromptPayments',
title: 'Creditor Prompt Payments',
settings: {
icon: 'usd',
roles: ["Employee", "Admin"]
}
},
{
route: "accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices",
name: "payments",
moduleId: PLATFORM.moduleName("../components/accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices/payOutstandingCreditorInvoices"),
href: '#accounting/creditorCostInvoices/payments/payOutstandingCreditorInvoices',
title: 'Pay Outstanding Creditor Invoices',
settings: {
icon: 'edit',
roles: ["Employee"/*, "Admin"*/]
}
},
],
}
},
]
}
},
]
}
}
]
}
Scheduler is one node and client is another however client has an array with three nodes.
Scheduler是一个节点,客户端是另一个节点,但客户端有一个包含三个节点的阵列。
I want to iterate over this and create a new array where if any of the nodes do not satisfy the role value then that node is left out while still maintaining the depth structure of the original array.. So in the menuList() if iterate over this checking if the role setting has "Admin" and it doesnt it ignores that node and I get a filtered array with just those nodes that have "Admin" in it.
我想迭代这个并创建一个新的数组,如果任何节点不满足角色值,那么该节点被遗漏,同时仍然保持原始数组的深度结构。所以在menuList()中迭代结束这检查角色设置是否具有“Admin”并且它不会忽略该节点,并且我得到一个过滤的数组,其中只有那些包含“Admin”的节点。
I did a monster "for loop" with nested "for loops" to try and capture this but failed.
我做了一个怪物“for loop”与嵌套的“for循环”尝试捕获这个但失败了。
I now thought I would use the let entry of someArray
but I am getting the error:
我现在以为我会使用someArray的let条目但是我收到了错误:
Error TS2349 (TS) Cannot invoke an expression whose type lacks a call signature. Type 'any[]' has no compatible call signatures
错误TS2349(TS)无法调用类型缺少调用签名的表达式。类型'any []'没有兼容的呼叫签名
Not sure how to fix this however...
不知道怎么解决这个问题...
Is there a smart way to filter this array based on role.includes("Admin")etc while still maintaining the structure?
是否有一种智能的方法来过滤基于role.includes(“Admin”)等的数组,同时仍然保持结构?
UPDATE
UPDATE
I finally managed to get this to work although I think there will be a multitude of better more succinct ways of doing it.
我终于设法让这个工作了,虽然我认为会有更多更简洁的方法。
I took the view of dealing with each node completely before moving to the next and to do this I used a recursive function calling itself for each level.
在进入下一个节点之前,我采取了完全处理每个节点的观点,为此我使用了一个为每个级别调用自身的递归函数。
public userMenu(userName: string, userRole: string): any {
let finishedRoleCheckedMenu = Array();
let userMenuElements = Array();
let returnedElement = {} as any;
for (const key in this.menuList()) {
returnedElement = this.processElement(this.menuList()[key], userRole);
if (returnedElement !== 'undefined') {
userMenuElements.push(returnedElement);
}
}
for (let count = 0; count < this.routeMenuItems.length; count++) {
if (!this.routeMenuItems[count].settings.divider) {
userMenuElements.push(this.routeMenuItems[count]);
}
}
return userMenuElements;
}
processElement(element: any, userRole: string) {
let testedElement = {} as any;
let settingsElement = {} as any;
let navElements = Array();
let navElement = {} as any;
if (element.settings.roles.includes(userRole)) {
for (const key in element) {
if (key === "settings") {
for (const settingsKey in element[key]) {
if (settingsKey === "nav") {
for (const navKey in element[key][settingsKey]) {
navElement = this.processElement(element[key][settingsKey][navKey], userRole); // recursive call.
if (navElement !== 'undefined') {
if (navElement.route) { // Collect only those elements with routes.
this.routeMenuItems.push(navElement); // For adding the total routes at the end.
}
navElements.push(navElement);
}
}
if (navElements.length > 0) {
settingsElement[settingsKey] = navElements;
}
} else {
settingsElement[settingsKey] = element[key][settingsKey];
}
}
testedElement[key] = settingsElement;
} else {
testedElement[key] = element[key];
}
}
return testedElement;
} else {
return 'undefined';
}
}
1 个解决方案
#1
1
The compiler is complaining about the caller code. Specifically whatever it plans on doing with the returned array. Reason for this is because you have specified the return type as "any". Perhaps return type of array may be more appropriate.
编译器抱怨调用者代码。特别是无论它计划如何处理返回的数组。原因是因为您已将返回类型指定为“any”。也许返回类型的数组可能更合适。
As far as filtering the array, I think you're on the right track, however you would be able to clean up the code a bit by using a map, or map/reduce pattern.
至于过滤数组,我认为你是在正确的轨道上,但是你可以通过使用map或map / reduce模式来清理代码。
#1
1
The compiler is complaining about the caller code. Specifically whatever it plans on doing with the returned array. Reason for this is because you have specified the return type as "any". Perhaps return type of array may be more appropriate.
编译器抱怨调用者代码。特别是无论它计划如何处理返回的数组。原因是因为您已将返回类型指定为“any”。也许返回类型的数组可能更合适。
As far as filtering the array, I think you're on the right track, however you would be able to clean up the code a bit by using a map, or map/reduce pattern.
至于过滤数组,我认为你是在正确的轨道上,但是你可以通过使用map或map / reduce模式来清理代码。