ABP框架中的Navigation功能用于管理业务系统中所有可用的菜单导航控件,通常在业务系统的首页会有一个全局性的导航菜单,JD商城,天猫,猪八戒网莫不如是。所以为方便起见,Navigation功能默认定义了一个"MainMenu"菜单添加到缓存字典中。该Navigation功能与普通ERP项目中可定制动态生成的导航菜单最大的区别应该是每一个菜单定义(MenuItemDefinition)可以设置一个权限只有用户拥有权限才会显示给该用户,控制更加的细更加的松耦合不是直接绑定到某个用户上。

  整体而言,Navigation分为两部分,第一部分是菜单定义部分,业务系统中所有可用菜单项的定义都会存储其中,第二部分是用户导向,是面向具体用户返回具体菜单信息,就是根据用户自身的权限过滤出一部分菜单定义项(MenuItemDefinition)并转换成UserMenuItem返回给用户。

  1.菜单定义

  菜单定义主要是MenuDefinition和MenuItemDefinition两类。前者代表一个菜单,会拥有一个MenuItemDefinition的集合表示所拥有的菜单选项,每一个MenuItemDefinition自身还会拥有子MenuItemDefinition的集合。

  业务项目开发者定义一个菜单的操作与上篇Feature的定义方式基本相同,定义一个集成自NavigationProvider的子类重写SetNavigation方法,在方法体中通过引用到的单例INavigationManager,注册进INavigationManager所拥有的一个缓存字典中,具体实例如下:

public class MyNavigationProvider1 : NavigationProvider
{
public override void SetNavigation(INavigationProviderContext context)
{
context.Manager.MainMenu.AddItem(
new MenuItemDefinition(
"Abp.Zero.Administration",
new FixedLocalizableString("Administration"),
"fa fa-asterisk",
requiresAuthentication: true
).AddItem(
new MenuItemDefinition(
"Abp.Zero.Administration.User",
new FixedLocalizableString("User management"),
"fa fa-users",
"#/admin/users",
requiredPermissionName: "Abp.Zero.UserManagement",
customData: "A simple test data"
)
).AddItem(
new MenuItemDefinition(
"Abp.Zero.Administration.Role",
new FixedLocalizableString("Role management"),
"fa fa-star-o",
"#/admin/roles",
requiredPermissionName: "Abp.Zero.RoleManagement"
)
)
);
}
}

在自定义的AbpModule中通过NavigationConfiguration注册到Providers属性中,而NavigationManager的Initialize方法会获取NavigationConfiguration的Providers逐个调用SetNavigation,完成整个菜单导航的注册。

  2.用户菜单

  真正会被用作菜单数据的用户菜单也有UserMenu和UserMenuItem两个类和上面的MenuDefinition和MenuItemDefinition是对应的,单例的UserNavigationManager提供了两个方法GetMenuAsync,GetMenusAsync,分别可以根据菜单导航名返回导航数据和根据用户Id,返回该用户所拥有的所有导航菜单。

  在GetMenuAsync,GetMenusAsync中会先获取全部的菜单定义项,根据定义项中是否拥有权限控制,有的话就制返回满足权限的菜单项。具体的逻辑如下:

private async Task<int> FillUserMenuItems(int? tenantId, long? userId, IList<MenuItemDefinition> menuItemDefinitions, IList<UserMenuItem> userMenuItems)
{
var addedMenuItemCount = ; using (var featureDependencyContext = _iocResolver.ResolveAsDisposable<FeatureDependencyContext>())
{
featureDependencyContext.Object.TenantId = tenantId; foreach (var menuItemDefinition in menuItemDefinitions)
{
if (menuItemDefinition.RequiresAuthentication && !userId.HasValue)
{
continue;
} if (!string.IsNullOrEmpty(menuItemDefinition.RequiredPermissionName) && (!userId.HasValue || !(await PermissionChecker.IsGrantedAsync(userId.Value, menuItemDefinition.RequiredPermissionName))))
{
continue;
} if (menuItemDefinition.FeatureDependency != null &&
(AbpSession.MultiTenancySide == MultiTenancySides.Tenant || tenantId.HasValue) &&
!(await menuItemDefinition.FeatureDependency.IsSatisfiedAsync(featureDependencyContext.Object)))
{
continue;
} var userMenuItem = new UserMenuItem(menuItemDefinition, _localizationContext);
if (menuItemDefinition.IsLeaf || (await FillUserMenuItems(tenantId, userId, menuItemDefinition.Items, userMenuItem.Items)) > )
{
userMenuItems.Add(userMenuItem);
++addedMenuItemCount;
}
}
} return addedMenuItemCount;
}

用户菜单就是这么简单。

ABP框架详解(五)Navigation的更多相关文章

  1. ABP框架详解(三)Domain

    此处的Domain主要指Abp类库根目录下Domain文件夹.顾名思义该目录下是用来存放与领域实体,领域逻辑执行,存储,领域服务相关的内容. 1.Entities (1)为整个Abp框架后期开发的所有 ...

  2. ABP框架详解(八)动态ApiController的生成和访问机制

    在ABP框架中提供了一套动态生成ApiController的机制(依然支持原生ApiController的使用方式),虽然说是动态生成ApiController但是实际上并没有真正在启动程序的时候生成 ...

  3. ABP框架详解(七)Caching

    在ABP框架中存在一个缓存机制,使用ICache的继承类来存储最终需要缓存的数据,可以吧ICache看成一个字典对象,使用Key作为真实数据的具有唯一性的表示.使用上与字典对象完全相同,Get方法传递 ...

  4. ABP框架详解(四)Feature

    ABP框架中存在一个Feature的特性,功能和设计思路非常类似于框架中的Authorization功能,都是来控制用户是否能够继续操作某项功能,不同点在于Authorization默认是应用在IAp ...

  5. ABP框架详解(二)AbpKernelModule

    AbpKernelModule类是Abp框架自己的Module,它也跟所有其他的Module一样继承自AbpModule,重写PreInitialize,Initialize,PostInitiali ...

  6. ABP框架详解(一)ABPBootstrapper

    在ABP框架的AbpBootstrapper主要用于框架的基本配置的注册和初始化,在Web应用启动阶段实例化一个AbpBootstrapper并调用Initialize方法初始化,该类主要包含两个公有 ...

  7. ABP框架详解(六)Aspects

    这种AOP式的设计非常类似于Asp.net MVC和WebApi中过滤器(Filter)机制,感觉没有太多可讲述的,只能谈谈设计思路. 框架中AspectAttribute特性用于设置到需要被拦截的T ...

  8. jQuery Validate验证框架详解

    转自:http://www.cnblogs.com/linjiqin/p/3431835.html jQuery校验官网地址:http://bassistance.de/jquery-plugins/ ...

  9. mina框架详解

     转:http://blog.csdn.net/w13770269691/article/details/8614584 mina框架详解 分类: web2013-02-26 17:13 12651人 ...

随机推荐

  1. 2016. last day in office

    外面黑了,水面上黑魆魆的看不清楚了. 明天请假了,2017年再见! 2017加油! 2017 English improving!

  2. Xcode中给控件添加颜色时自动显示出颜色

    在iOS开发中,给一些控件设置颜色的时候,设置完不能立马看到颜色.必须要运行程序之后才能看到设置的颜色,如果颜色有偏差再回代码改参数,然后再运行看颜色很是麻烦.令人高兴得是Xcode有很多功能强大插件 ...

  3. genymotion不能联网

    1.打开Oracle VM Virtual Box,选中相应的虚拟机,点击上侧工具栏中的『设置』: 2.选择『网络』,接着将: 网卡1的连接方式设置为仅主机(Host-Only)适配器: 将网卡2设置 ...

  4. HYSBZ 4551 (树状数组) 采花

    题目:这里 题意: 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记, ...

  5. codeforces 704A (队列模拟) Thor

    题目:这里 题意:n个app,q个操作,当操作数type为1的时候表示y这个app推送了你一条消息,当操作数type为2的时候表示将y这个app已推送的所有消息都读完,当操作数为3的时候 表示将已经推 ...

  6. iOS.DistributionApp.0-build-adhoc-distribution-for-tester

    Build adhoc distribution for tester 1. 提供App测试包 1.1 提供测试包的步骤 Ref[8] A: 注册所有的测试设备 B: 将App进行归档 C: 用ad ...

  7. 微信公众账号开发之N个坑(二)

    上篇说到微信公众账号的几个坑,前面五个,已经说到菜单,宝宝继续往下赘述了.可惜,还不知道宝宝的宝宝到底是不是心疼宝宝呢,完了,我凌乱了... 回到正题,我们就不吐槽其他的了,上一篇说到微信的菜单了,那 ...

  8. System.Security.SecurityException The source was not found, but some or all event logs could not be searched.Inaccessible logs Security.

    An exception occurred during the Install phase. System.Security.SecurityException The source was not ...

  9. 图片预加载和AJAX的图片预加载

    利用js实现图片预加载,加载所需要图片的路径与名称即可,很容易实现,该方法尤其适用预加载大量的图片: <div class="hidden"> <script t ...

  10. Spring JdbcTemplate 调用存储过程

    遇到调用存储过程的业务,以前有用过,但不是用Spring的 JdbcTemplate去做的,这次是在一个已经有的SpringMVC框架的项目下写处理存储过程的. 参考网络中的方法,在实际操作中遇到两个 ...