我正在开发一个菜单页面,用户可以在其中根据他们的 Angular 色查看菜单项。
目前,我有 3 个页面:公告板、信息中心 和设置
很自然地,我有 3 个 Angular 色:Admin Role(可以访问所有 3 个页面),Bulletin Board(只能访问 Bulletin Board),信息中心(只能访问信息中心)
因此用户可以有不同的 Angular 色,例如,如果他们有Bulletin Board 和Info Hub,那么他们可以同时访问它们,但不能访问>Settings页面(只有“Admin Role”可以看到Settings),所以我想隐藏我已经开发和渲染的这个菜单中的Settings使用 map
。
或者,如果用户拥有所有 3 个 Angular 色,包括管理员 Angular 色,那么他们也可以看到所有内容。
我从 API 获取 loginList
属性并将其传递到 AllAppsCentre.js 以确定要显示的菜单项,但我无法确定找出在 map
处执行 filter
或 indexOf
的逻辑。
在我创建的 codesandbox 中,用户拥有所有 3 个 Angular 色。
AllAppsCentre.js(显示菜单项的映射函数)
useEffect(() => {
const loginListFromParent = loginList;
const showAll = loginListFromParent.some(
(item) =>
item.permissionName.includes("Admin Role") &&
item.permissionType.includes("view")
);
const showBulletin = loginListFromParent.some(
(item) =>
item.permissionName.includes("Bulletin Board") &&
item.permissionType.includes("view")
);
const showInfoHub = loginListFromParent.some(
(item) =>
item.permissionName.includes("Info Hub") &&
item.permissionType.includes("view")
);
if (loginListFromParent) {
setShowAll(showAll);
setShowBulletin(showBulletin);
setShowInfoHub(showInfoHub);
}
}, [loginList]);
return (
{AllAppsCentreData
.filter((item) => {
.map((item, index) => {
return (
<Col key={index} xs={6} md={3}>
<div className={item.className}>
<Link to={item.path}>
{item.icon}
<Row>
<span className='apps-title'>
{item.title}
</span>
</Row>
</Link>
</div>
</Col>
)
})}
)
AllAppsCentreData.js
import * as IoIcons from 'react-icons/io'
import * as MdIcons from 'react-icons/md'
export const AllAppsCentreData = [
{
title: 'Bulletin Board',
path: '/bulletinboard',
icon: <IoIcons.IoIosPaper size={80} />,
className: 'row text-center apps-centre-icon'
},
{
title: 'Info Hub',
path: '/infohub',
icon: <MdIcons.MdDeviceHub size={80} />,
className: 'row text-center apps-centre-icon'
},
{
title: 'Settings',
path: '/settings',
icon: <IoIcons.IoMdSettings size={80} />,
className: 'row text-center apps-centre-icon'
},
]
我一直在想办法解决这个问题,但我就是想不出一个解决方案,如果一切都失败了,我可能只是删除 map 方法,然后复制并粘贴我的 AllAppsCentreData 的项目并将其直接移动到 AllAppsCentre 页面,这样我就可以在菜单项上进行三元操作。
如果有任何更好的方法来使用基于 Angular 色的显示来执行此菜单,请随时告诉我,因为我也想学习执行此类操作的最佳方法。
最佳答案
首先,您的代码中没有变量负责保存当前用户的权限(或者我看不到)。所以我编了:
const currentUsersPermissions = useGetPermissions() // get users permissions
// the above can be "admin", "bulletin" or "info-hub"
然后,你需要先filter
你的数组,然后map
它(目前,你在filter中使用
)。为了更容易和正确地做到这一点,您可以向您的 map
AllAppsCentreData
对象添加一个名为 requiredPermission
的属性(或类似的东西):
{
title: 'Bulletin Board',
path: '/bulletinboard',
icon: <IoIcons.IoIosPaper size={80} />,
className: 'row text-center apps-centre-icon',
requiredPermission: "bulletin" // and info-hub for Info Hub
},
然后,在渲染和贴图的时候,你可以这样做:
return (
{AllAppsCentreData
.filter(
// below, you return true if permission is admin because he can see everything
// and true or false depending if permissions are other than that but
// the same as required by AllAppsCentreData array objects
(item) => currentUsersPermissions === "admin" ? true : currentUsersPermissions === item.requiredPermission
).map((item, index) => {
return (
<Col key={index} xs={6} md={3}>
<div className={item.className}>
<Link to={item.path}>
{item.icon}
<Row>
<span className='apps-title'>
{item.title}
</span>
</Row>
</Link>
</div>
</Col>
)
)
所以,总结一下:
- 我创建了一个变量来保存当前用户的权限
- 我已经为每个 AllAppsCentreData 的对象添加了一个属性,其中包含有关显示它所需的权限的信息
- 我在映射和渲染之前过滤了数组,所以它只包含我想要渲染的数据
此外,我认为您在使用filter
方法时迷失了方向,所以也许阅读此内容并尝试做一些更简单的练习以了解其工作原理:MDN on Array.filter method .您需要注意的是,您向filter
传递了一个函数,这个函数应该返回true
或false
,这取决于您是否想要您的项目包含在输出数组中。
关于javascript - 如何在特定条件下排除 map 中的特定项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69115900/