每一個網站都會有導航菜單(通常不止一個),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 用於取得應用程序的主菜單。
