DDD开发框架ABP之导航菜单

      每一个网站都会有导航菜单(通常不止一个),ASP.NET Boilerplate(后文简称ABP)提供了一种创建和使用菜单的通用架构,利用架构我们可以方便的创建菜单并显示给用户。本文主要说明菜单的创建,以及结合AngularJS上菜单的显示,如何从数据库动态取得菜单数据不再本文范围。

创建菜单

      一个应用程序可能有多个不同的模块,每个模块有它对应的菜单项。为了定义这些菜单项,我们需要创建一个继承自 NavigationProvider 的子类。
      假设我们有一个如下所示的主菜单:

   工作台
   任务
   留言板
   系统管理
      用户管理
      角色管理

      这里面系统管理菜单有两个子菜单项。建立一个这样菜单的类ZeroNavigationProvider,如下:

 1 public class ZeroNavigationProvider : NavigationProvider
 2 {
 3       public override void SetNavigation(INavigationProviderContext context)
 4       {
 5             context.Manager.MainMenu
 6                   .AddItem(
 7                         new MenuItemDefinition(
 8                               "Dashboard",
 9                               new LocalizableString("HomePage", "Zero"),
10                               url: "#/",
11                               icon: "icon-home"
12                         )
13                   ).AddItem(
14                         new MenuItemDefinition(
15                               "Task",
16                               new LocalizableString("Task", "Zero"),
17                               url: "#/tasklist",
18                               icon: "icon-tag"
19                         )
20                   ).AddItem(
21                         new MenuItemDefinition(
22                               "QA",
23                               new LocalizableString("QA", "Zero"),
24                               url: "#/qa",
25                               icon: "icon-question"
26                         )
27                   ).AddItem(
28                         new MenuItemDefinition(
29                               "SystemAdmin",
30                               new LocalizableString("SystemAdmin", "Zero"),
31                               icon: "icon-wrench"
32                         ).AddItem(
33                               new MenuItemDefinition(
34                                     "UserManage",
35                                     new LocalizableString("UserManage", "Zero"),
36                                     url: "/systemadmin/users",
37                                     icon: "icon-users"
38                               )
39                         ).AddItem(
40                               new MenuItemDefinition(
41                                     "RoleManage",
42                                     new LocalizableString("RoleManage", "Zero"),
43                                     url: "/systemadmin/role",
44                                     icon: "icon-briefcase"
45                               )
46                         );
47                }
48  }

      一个MenuItemDefinition对象可能拥有一个唯一的命名,一个本地化显示的名称,一个URL地址以及一个图标。一个菜单项也可能需要拥有特定权限的用户才可以浏览。

1 new MenuItemDefinition(
2     "RoleManage",
3     new LocalizableString("RoleManage", "Zero"),
4     url: "/systemadmin/role",
5     icon: "icon-briefcase",
6     requiredPermissionName: "systemadmin",
7     requiresAuthentication:true
8 )

      本地化显示的名称来自于资源文件,LocalizableString第二个参数就是系统中资源文件的名称。这时候需要确保资源文件存在,比如:Zero-zh-CN.xml,而且根据第一个代码参数必须能够正常取出对应的文本内容,否则菜单可能无法显示。
INavigationProviderContext 提供了一些方法接口,用于得到已经存在的菜单项,添加菜单以及子菜单。因此不同的模块能够添加自己的菜单项。
      一个应用程序可能有多个菜单,context.Manager.MainMenu 只是对应默认的主菜单。我们可以利用 context.Manager.Menus 属性自己创建并添加更多的菜单。
      创建了 NavigationProvider 之后,我们需要将它注册到ABP的配置项中,这个动作应该放在我们模块的 PreInitialize 事件中。比如我们网站的Web层有一个 ZeroWebModule,在其中添加代码:

1 public override void PreInitialize()
2 {
3     // other configuration code, like localization
4     // Configure navigation/menu
5     Configuration.Navigation.Providers.Add<ZeroNavigationProvider>();
6 }

显示菜单

      我们能够在服务器端创建菜单。Abp.Application.Navigation 命名空间下的 IUserNavigationManager 接口通过依赖注入,实现菜单项的取得和显示。服务器端创建菜单通常用于ASP.NET MVC 的多页面网站,这里略过不表。

      我们也可以在客户端创建菜单。ABP自动产生Javascript API ,使得我们在客户端可以轻松取得菜单和菜单项。做到这一点,我们只需要在网页引入下面的一行代码(动态生成的Javascript):

<script src="~/AbpScripts/GetScripts" type="text/javascript"></script>

      在调试状态下,我们可以查看动态生成的Javascript代码,其中有一段关于导航菜单的定义:

 1 (function() {
 2     abp.nav = {};
 3     abp.nav.menus = {
 4         'MainMenu': {
 5             name: 'MainMenu',
 6             displayName: 'Main menu',
 7             items: [{
 8                 name: 'Dashboard',
 9                 icon: 'icon-home',
10                 url: '#/',
11                 displayName: '工作台',
12                 items: []
13             } , {
14                 name: 'Task',
15                 icon: 'icon-tag',
16                 url: '#/task',
17                 displayName: '任务',
18                 items: []
19             } , {
20                 name: 'QA',
21                 icon: 'icon-question',
22                 url: '#/qa',
23                 displayName: '留言板',
24                 items: []
25             } , {
26                 name: 'SystemAdmin',
27                 icon: 'icon-wrench',
28                 displayName: '系统管理',
29                 items: [{
30                     name: 'UserManage',
31                     icon: 'icon-users',
32                     url: '/systemadmin/users',
33                     displayName: '用户管理',
34                     items: []
35                 } , {
36                     name: 'RoleManage',
37                     icon: 'icon-briefcase',
38                     url: '/systemadmin/rolelist',
39                     displayName: '角色管理',
40                     items: []
41                 }]
42             };
43         }
44 })();

      在Javascript 里面我们就可以使用 abp.nav 命名空间下的方法和属性,比如:abp.nav.menus.MainMenu 用于取得应用程序的主菜单。

 

posted @ 2015-09-28 09:34  朱优良  阅读(3630)  评论(1编辑  收藏  举报