我在遍历嵌套数组时遇到问题,该嵌套数组可以包含本身的数组...应该代表如下动态菜单:
这是对象的制造方式:
Interface IMenuNode:
export interface IMenuNode {
title: string;
haveChildren: boolean;
id: string;
node: Array<IMenuNode>;
link: string;
img: string;
value: string;
}
Class DataNode that implements IMenuNode
export class DataNode implements IMenuNode {
title: string;
haveChildren: boolean;
id: string;
node: Array<IMenuNode>;
link: string;
img: string;
value: string;
userMenu: Array<IMenuNode>;
现在我在MenuData中有一些信息,如下所示:
const MenuData: Array<IMenuNode> =
[
new DataNode('Menu 1', true, 'menu1', [
new DataNode('SubMenu 1', true, 'submenu1',[
new DataNode('SubSubMenu1', false ,'subsubmenu1', null, "/", "pathSelectorIcon.png"),
new DataNode('SubSubmenu2', false, 'subsubmenu2', null ,"/", "pathSelectorIcon.png"),
]),
new DataNode('Menu 2', true, 'menu2', [
new DataNode('SubMenu 1', true, 'submenu1',[
new DataNode('SubSubMenu1', false ,'subsubmenu1', null, "/", "pathSelectorIcon.png"),
new DataNode('SubSubmenu2', false, 'subsubmenu2', null ,"/", "pathSelectorIcon.png"),
]),
如何根据某些条件(甚至以递归方式)循环整个MenuData并动态构建新菜单(userMenu) 选择新菜单应包含的项目(菜单和子菜单)?
答案 0 :(得分:0)
下面的函数显然可以满足您的期望,希望对您有所帮助。
userMenu = newUserMenu(MenuData);
function newUserMenu(original: Array<IMenuNode>): Array<IMenuNode> {
const newMenu: Array<IMenuNode> = []
for (let menu of original) {
if (User.hasAccess(menu)) { // Or other conditions
// To ensure new reference
// Note not passing the children, it must pass through recursive method below
const newNode = new DataNode(menu.title, menu.haveChildren, menu.id, null, menu.link, menu.img, menu.value);
newMenu.push(newNode);
if (newNode.haveChildren) {
newNode.node = newUserMenu(menu.node);
}
}
}
return newMenu;
}
我也编辑了您的类和界面,以确保构造像示例一样工作。
interface IMenuNode {
title: string;
haveChildren: boolean;
id: string;
node?: Array<IMenuNode>;
link?: string;
img?: string;
value?: string;
}
class DataNode implements IMenuNode {
constructor(
public title: string,
public haveChildren: boolean,
public id: string,
public node?: Array<IMenuNode>,
public link?: string,
public img?: string,
public value?: string,
) { }
}
编辑:在新菜单中添加当前级别之前验证孩子的新示例。
// The new function only add the "dir" menus if they have children where the user have access
function newUserMenu2(original: Array<IMenuNode>): Array<IMenuNode> {
const newMenu: Array<IMenuNode> = [];
for (let menu of original) {
if (User.hasAccess(menu)) {// Or other conditions
// To ensure new reference
// Note not passing the children, it must pass through recursive method below
const newNode = new DataNode(menu.title, menu.haveChildren, menu.id, null, menu.link, menu.img, menu.value);
if (newNode.haveChildren) {
newNode.node = newUserMenu2(menu.node);
}
// Note, only add the menu if it has a link or if it "stores" a menu that the user has access and that has a link
if (Array.isArray(newNode.node) && newNode.node.length > 0 || newNode.link) {
newMenu.push(newNode);
}
}
}
return newMenu;
}