ABP入门系列目录——学习Abp框架之实操演练
源码路径:Github-LearningMpaAbp


完成了增删改查以及页面展示,这一节我们来为任务清单添加【导航菜单】。
在以往的项目中,大家可能会手动在layout页面中添加一个a标签来新增导航菜单,这也是一种方式,但是如果要针对不同用户不同权限决定是否显示某个菜单,那么直接在layout页面中去控制就不方便了。
不过,ABP已经为大家考虑了这一点,集成了通用的创建和显示菜单的方式。其主要代码集成在Abp.Application.Navigation命名空间下,相应源码在此。
下面我们就来梳理下导航菜单是如何实现和使用。

一、如何使用Abp集成的导航菜单

针对我们的『任务清单』Deom,我们需要在导航栏上添加一个【Task List】的菜单入口。

1.打开web展现层,定位到App_Start/xxxNavigationProvider.cs。

    public class LearningMpaAbpNavigationProvider : NavigationProvider{public override void SetNavigation(INavigationProviderContext context){context.Manager.MainMenu.AddItem(new MenuItemDefinition("Home",L("HomePage"),url: "",icon: "fa fa-home",requiresAuthentication: true)).AddItem(new MenuItemDefinition("Tenants",L("Tenants"),url: "Tenants",icon: "fa fa-globe",requiredPermissionName: PermissionNames.Pages_Tenants)).AddItem(new MenuItemDefinition("Users",L("Users"),url: "Users",icon: "fa fa-users",requiredPermissionName: PermissionNames.Pages_Users)).AddItem(new MenuItemDefinition("About",L("About"),url: "About",icon: "fa fa-info"));}
}

该文件中默认定义了Home、Tenants、Users、About四个菜单。注意观察的话,想必会注意到Home菜单设置了requiresAuthentication: true,即只有登陆后才会显示该菜单。Tenants和Users菜单设置了requiredPermissionName属性,即用户具有指定的权限时才显示菜单。About菜单没有限制,默认显示。
每一个菜单项都是一个MenuItemDefinition,其中主要包括Name(唯一名称),DisplayName(本地化显示名称),Url(菜单跳转),Icon(指定菜单图标)。
解释到这里,大家自己都可以依葫芦画瓢,新增菜单了。

2.添加[Task List]菜单项

AddItem(new MenuItemDefinition("TaskList",L("Task List"),url: "Tasks/Index",icon: "fa fa-tasks",requiresAuthentication: true)

保存,刷新页面即可看到新增的[Task List]菜单了。

PS:之所以页面上会显示为[Task List],是因为我们并没有维护本地化资源文件。在对应的本地化配置文件中新增名为"Task List"的即可。比如在中文的本地化文件中添加
<text name="Task List" value="任务清单" />,重新启站点,将语言切换为中文。


二、Abp集成的导航菜单的代码结构

1.先来看看相关代码的类型依赖关系图

类型依赖关系图

分析发现,abp集成的导航菜单实际上是应用了组合设计模式。
其中MenuDefinition为根节点,MenuItemDefinition为树枝节点,其中MenuItemDefinition中也维护了一个List<MenuItemDefinition>的集合,当集合为空时,MenuItemDefinition即为树叶节点。

2.从图中可以看出,主要是由以下几部分组成:

  • MenuDefinition/MenuItemDefinition:菜单/菜单项定义。其中菜单项包括Name(唯一名称),DisplayName(本地化显示名称),Url(菜单跳转),Icon(指定菜单图标)。此外,可以通过指定RequiresAuthentication=true来限制菜单项只有对登录用户可见,同时也可以指定RequiredPermissionName来限定当用户有某个权限时菜单才可见。
  • UserMenu/UserMenuItem:封装了用于显示给用户的菜单/子菜单集合。
  • INavigationConfiguration/NavigationConfiguration:导航配置,维护了NavigationProvider的列表。
  • NavigationProvider:Provider模式(将api的定义和实现分离)。抽象类,定义了SetNavigation方法,在需要设置导航的项目中实现该类,并在对应的模块中PreInitialize方法中注册***NavigationProvider的实现。
  • INavigationManager/NavigationManager:其中接口中定义了一个Dictionary,用来存储应用程序中定义的所有菜单项,和一个MainMenu。注入了对INavigationConfiguration的引用,以便在NavigationManager中的Initialize方法遍历INavigationConfiguration配置的NavigationProvider列表进行菜单的初始化。
    IUserNavigationManager/UserNavigationManager:是对NavigationManager的一次封装。其中接口中定义了GetMenuAsync的重载方法,用来获取指定用户的菜单。
  • INavigationProviderContext/NavigationProviderContext:封装了INavigationManager的上下文类,用于传参。

三、Abp集成的导航菜单的具体实现

核心逻辑:NavigationManager遍历NavigationConfiguration中维护的NavigationProvider列表,并调用NavigationProvider实现的SetNavigation方法来完成导航菜单的初始化。

NavigationManager负责初始化菜单

NavigationManager.cs

NavigationConfiguration负责维护NavigationProvider的实现列表。

NavigationConfiguration.cs

具体的NavigationProvider的实现

xxxxNavigationProvider.cs

在对应的模块中注册具体的NavigtionProvider到INavigationConfiguration维护的列表中。

xxxxAbpWebModule.cs

UserNavigationManager对NavigationManager进行了进一步的封装,根据用户和权限去创建和获取菜单。

IUserNavigationManager.cs

在LayoutController中,通过注入对IUserNavigationManager的引用,来获取菜单,并由_TopMenu分部页进行最终呈现。

public class LayoutController : LearningMpaAbpControllerBase{private readonly IUserNavigationManager _userNavigationManager;private readonly ISessionAppService _sessionAppService;private readonly IMultiTenancyConfig _multiTenancyConfig;private readonly ILanguageManager _languageManager;public LayoutController(IUserNavigationManager userNavigationManager, ISessionAppService sessionAppService, IMultiTenancyConfig multiTenancyConfig,ILanguageManager languageManager){_userNavigationManager = userNavigationManager;_sessionAppService = sessionAppService;_multiTenancyConfig = multiTenancyConfig;_languageManager = languageManager;}[ChildActionOnly]public PartialViewResult TopMenu(string activeMenu = ""){var model = new TopMenuViewModel{MainMenu = AsyncHelper.RunSync(() => _userNavigationManager.GetMenuAsync("MainMenu", AbpSession.ToUserIdentifier())),ActiveMenuItemName = activeMenu};return PartialView("_TopMenu", model);}
}

至此,我们完成了对导航菜单的梳理和总结。

11人点赞

Abp架构入门系列

作者:圣杰
链接:https://www.jianshu.com/p/24e6f6e8dbdb
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

ABP入门系列(6)——定义导航菜单相关推荐

  1. [置顶]ABP入门系列目录——学习Abp框架之实操演练

    本系列文章主要是基于ABP模板开发Mpa(多页面)『任务清单』项目. 由于是入门系列,不会用到代码生成器,每一行代码都是手动敲入. 源码已上传至Github-LearningMpaAbp,可自行参考. ...

  2. ABP入门系列(7)——分页实现

    ABP入门系列目录--学习Abp框架之实操演练 完成了任务清单的增删改查,咱们来讲一讲必不可少的的分页功能. 首先很庆幸ABP已经帮我们封装了分页实现,实在是贴心啊. 来来来,这一节咱们就来捋一捋如何 ...

  3. ABP入门系列(14)——应用BootstrapTable表格插件

    1. 引言 之前的文章ABP入门系列(7)--分页实现讲解了如何进行分页展示,但其分页展示仅适用于前台web分页,在后台管理系统中并不适用.后台管理系统中的数据展示一般都是使用一些表格插件来完成的.这 ...

  4. ABP入门系列(5)——展现层实现增删改查

    ABP入门系列目录--学习Abp框架之实操演练 源码路径:Github-LearningMpaAbp 这一章节将通过完善Controller.View.ViewModel,来实现展现层的增删改查.最终 ...

  5. ABP入门系列(4)——创建应用服务

    ABP入门系列目录--学习Abp框架之实操演练 1. 解释下应用服务层 应用服务用于将领域(业务)逻辑暴露给展现层.展现层通过传入DTO(数据传输对象)参数来调用应用服务,而应用服务通过领域对象来执行 ...

  6. ABP入门系列(7)——分页实现_0

    ABP入门系列目录--学习Abp框架之实操演练 完成了任务清单的增删改查,咱们来讲一讲必不可少的的分页功能. 首先很庆幸ABP已经帮我们封装了分页实现,实在是贴心啊. 来来来,这一节咱们就来捋一捋如何 ...

  7. ABP入门系列(8)——Json格式化

    ABP入门系列目录--学习Abp框架之实操演练 源码路径:Github-LearningMpaAbp 讲完了分页功能,这一节我们先不急着实现新的功能.来简要介绍下Abp中Json的用法.为什么要在这一 ...

  8. abp.ajax get,ABP入门系列之Json格式化

    讲完了分页功能,这一节我们先不急着实现新的功能.来简要介绍下Abp中Json的用法.为什么要在这一节讲呢?当然是做铺垫啊,后面的系列文章会经常和Json这个东西打交道. 一.Json是干什么的 JSO ...

  9. ABP入门系列(12)——如何升级Abp并调试源码

    1. 升级Abp 本系列教程是基于Abp V1.0版本,现在Abp版本已经升级至V1.4.2,其中新增了New Feature,并对Abp做了相应的Enhancements,以及Bug fixs.现在 ...

最新文章

  1. python二进制转字符串
  2. 13.5 常见Random类
  3. 柿子不能和什么同吃?柿子相克食物大盘点
  4. Nginx配置报错unknown directive echo的解决
  5. 2017年第1贴:EXT.JS使用MVC模式时,注意如何协调MODEL, STORE,VIEW,CONTROLLER的关系
  6. wenzhixin bootstrap-table 点击table单元格改变颜色
  7. linux下用c语言写黄金矿工,C语言写的黄金矿工O(∩_∩)O---初稿,能玩了
  8. hdu 4283 You Are the One ( dp 2012 ACM/ICPC Asia Regional Tianjin Online )
  9. 跑毒的乌龟-0 : 随机漫步
  10. BZOJ2732[HNOI2012] 射箭
  11. MacBook上内容太大无法拷贝到U盘问题的解决
  12. 【PS】PS改变字体大小的方法
  13. Ruby File.open 方法打开文件和File.new 方法打开文件的差别
  14. 河南的抗疫英雄(C语言嘞)
  15. vue仿淘宝京东商品多条件筛选(vue实现)
  16. 利用freemarker实现word导出
  17. 【软件测试】资深测试聊一聊,测试架构师是怎么样的,做一名成功的测试工程师......
  18. python字典求平均值_Python
  19. MT6129射频处理器,MT6129芯片原理资料介绍
  20. csp-s模拟测试49(9.22)养花(分块/主席树)·折射(神仙DP)·画作

热门文章

  1. scikit-learn 学习笔记-- Generalized Linear Models (三)
  2. Spring基础学习笔记-Bean的基础知识
  3. 有关软件工程的问题的分析和讨论及课后的作业3
  4. spring 4.0 JUnit简单的Dao,Service测试
  5. Android Service 的一些笔记
  6. 用js将form表单同时提交到两个不同页面的方法
  7. 875. Koko Eating Bananas
  8. flex 下对齐_flex布局
  9. Linux表空间扩容,linux下oracle表空间导致磁盘空间不足
  10. 裸奔浏览器_躲进浏览器隐私模式就安全了吗?相当于闭着眼睛裸奔