abp web.mvc專案中的選單載入機制
阿新 • • 發佈:2020-05-12
# abp中的選單載入機制
在abp中選單的定義與我們傳統寫的框架不一樣,它是在編寫程式碼的時候配置,而我們一般寫的通用許可權管理系統中,是後期在後臺介面中新增的。這一點有很大不同。abp關於選單的定義及管理挺複雜的。
## 與選單相關的結構類、介面及擴充套件方法類
+ MenuDefinition:定義應用程式的選單的結構
+ MenuItemDefinition:定義應用程式的選單項的結構
+ IHasMenuItemDefinitions: 定義子選單的介面
+ HasMenuItemDefinitionsExtensions:查詢子選單項的擴充套件方法類
+ MenuItemDefinitionExtensions:操作選單項的擴充套件方法類
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/2020051220392097.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbmdrb25ndGlhbnl1emhhbw==,size_16,color_FFFFFF,t_70)
---
+ UserMenu:單個使用者的選單結構
+ UserMenuItem:單個使用者的選單中的選單項
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200512203944234.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbmdrb25ndGlhbnl1emhhbw==,size_16,color_FFFFFF,t_70)
## 與選單相關的操作類
這裡分為兩類,一類是針對應用系統的選單:
+ NavigationProvider:提供設定應用系統導航選單及選單項的方法SetNavigation
+ INavigationProviderContext:Provider模式的上下文介面
+ NavigationProviderContext:Provider模式的上下文類,設定NavigationManager
+ INavigationManager:導航選單管理應用服務介面
+ NavigationManager:導航選單管理應用服務類,包括構造預設主選單,初始化選單的所有選單項方法。
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200512204015973.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbmdrb25ndGlhbnl1emhhbw==,size_16,color_FFFFFF,t_70)
另一類是針對使用者選單的操作:
+ IUserNavigationManager: 使用者選單管理應用服務介面
+ UserNavigationManager:使用者選單管理應用服務類,提供了獲取指定使用者的選單, 根據使用者許可權填充選單項方法。
![在這裡插入圖片描述](https://img-blog.csdnimg.cn/20200512204039905.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3hpbmdrb25ndGlhbnl1emhhbw==,size_16,color_FFFFFF,t_70)
上面的所有類及介面都是在Abp這個專案中定義的。
## Web.MVC中的選單應用
### 選單的定義
選單定義在ContosoAbp.Web.Startup名稱空間下的ContosoAbpNavigationProvider類中,這裡ContosoAbp為自定義的專案名。ContosoAbpNavigationProvide繼承自NavigationProvider抽象類,是實際選單的定義者。這裡利用了Provider模式,微軟經常用這種模式。
```c#
using Abp.Application.Navigation;
using Abp.Authorization;
using Abp.Localization;
using ContosoAbp.Authorization;
namespace ContosoAbp.Web.Startup
{
///
/// This class defines menus for the application.
/// 定義應用程式的選單
///
public class ContosoAbpNavigationProvider : NavigationProvider
{
public override void SetNavigation(INavigationProviderContext context)
{
context.Manager.MainMenu
.AddItem(
new MenuItemDefinition( //首頁
PageNames.Home,
L("HomePage"),
url: "",
icon: "fas fa-home",
requiresAuthentication: true,
order:0
)
).AddItem(
new MenuItemDefinition( //空頁面
PageNames.Empty,
L("EmptyPage"),
url: "Home/Empty",
icon: "fas fa-home",
requiresAuthentication: false,
order: 1
)
).AddItem(
new MenuItemDefinition( //附件
PageNames.Attachment,
L("Attachment"),
url: "Attachment",
icon: "fas fa-home",
requiresAuthentication: false,
order: 2
)
).AddItem(
new MenuItemDefinition( //租戶
PageNames.Tenants,
L("Tenants"),
url: "Tenants",
icon: "fas fa-building",
permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_Tenants),
order: 3
)
).AddItem(
new MenuItemDefinition( // 使用者
PageNames.Users,
L("Users"),
url: "Users",
icon: "fas fa-users",
permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_Users),
order: 4
)
).AddItem(
new MenuItemDefinition( //角色
PageNames.Roles,
L("Roles"),
url: "Roles",
icon: "fas fa-theater-masks",
permissionDependency: new SimplePermissionDependency(PermissionNames.Pages_Roles),
order: 5
)
)
.AddItem(
new MenuItemDefinition( //關於
PageNames.About,
L("About"),
url: "About",
icon: "fas fa-info-circle",
order: 6
)
).AddItem( // Menu items below is just for demonstration!
new MenuItemDefinition( //多級選單
"MultiLevelMenu",
L("MultiLevelMenu"),
icon: "fas fa-circle",
order: 7
).AddItem(
new MenuItemDefinition(
"AspNetBoilerplate",
new FixedLocalizableString("ASP.NET Boilerplate"),
icon: "far fa-circle"
).AddItem(
new MenuItemDefinition(
"AspNetBoilerplateHome",
new FixedLocalizableString("Home"),
url: "https://aspnetboilerplate.com?ref=abptmpl",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetBoilerplateTemplates",
new FixedLocalizableString("Templates"),
url: "https://aspnetboilerplate.com/Templates?ref=abptmpl",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetBoilerplateSamples",
new FixedLocalizableString("Samples"),
url: "https://aspnetboilerplate.com/Samples?ref=abptmpl",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetBoilerplateDocuments",
new FixedLocalizableString("Documents"),
url: "https://aspnetboilerplate.com/Pages/Documents?ref=abptmpl",
icon: "far fa-dot-circle"
)
)
).AddItem(
new MenuItemDefinition(
"AspNetZero",
new FixedLocalizableString("ASP.NET Zero"),
icon: "far fa-circle"
).AddItem(
new MenuItemDefinition(
"AspNetZeroHome",
new FixedLocalizableString("Home"),
url: "https://aspnetzero.com?ref=abptmpl",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetZeroFeatures",
new FixedLocalizableString("Features"),
url: "https://aspnetzero.com/Features?ref=abptmpl",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetZeroPricing",
new FixedLocalizableString("Pricing"),
url: "https://aspnetzero.com/Pricing?ref=abptmpl#pricing",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetZeroFaq",
new FixedLocalizableString("Faq"),
url: "https://aspnetzero.com/Faq?ref=abptmpl",
icon: "far fa-dot-circle"
)
).AddItem(
new MenuItemDefinition(
"AspNetZeroDocuments",
new FixedLocalizableString("Documents"),
url: "https://aspnetzero.com/Documents?ref=abptmpl",
icon: "far fa-dot-circle"
)
)
)
);
}
private static ILocalizableString L(string name)
{
return new LocalizableString(name, ContosoAbpConsts.LocalizationSourceName);
}
}
}
```
### 選單的載入
選單的載入是利用的檢視元件,定義了一個SideBarMenuViewComponent的檢視元件,在這個SideBarMenuViewComponent類中,利用IUserNavigationManager獲取使用者的選單,返回SideBarMenuViewModel給前端,前端遍歷輸出選單及子項。
> 後端檢視元件的定義
```c#
using System.Threading.Tasks;
using Abp.Application.Navigation;
using Abp.Runtime.Session;
using Microsoft.AspNetCore.Mvc;
namespace ContosoAbp.Web.Views.Shared.Components.SideBarMenu
{
///
/// 側邊欄檢視元件
///
public class SideBarMenuViewComponent : ContosoAbpViewComponent
{
///
/// 側邊欄使用者導航管理
///
private readonly IUserNavigationManager _userNavigationManager;
///
/// Session服務
///
private readonly IAbpSession _abpSession;
///
/// 建構函式
///
///
///
public SideBarMenuViewComponent(
IUserNavigationManager userNavigationManager,
IAbpSession abpSession)
{
_userNavigationManager = userNavigationManager;
_abpSession = abpSession;
}
public async Task InvokeAsync()
{
var model = new SideBarMenuViewModel
{
MainMenu = await _userNavigationManager.GetMenuAsync("MainMenu", _abpSession.ToUserIdentifier())
};
return View(model);
}
}
}
```
> 前端遍歷輸出選單
```html
@using ContosoAbp.Web.Views.Shared.Components.SideBarMenu
@model SideBarMenuViewModel
@{
var orderedMenuItems = Model.MainMenu.Items.Where(x => x.IsVisible).OrderByCustom().ToList();
}