ps:本文需要先把abp的源碼下載下傳一份來下,跟着一起找實作,更容易懂
在abp中,對于權限和菜單使用靜态來管理,菜單的加載是在登陸頁面的地方(具體是怎麼知道的,浏覽器按F12,然後去sources中去找)

這個/AbpScripts/GetScripts是擷取需要初始化的script,源自AbpScriptsController,GetScripts方法包括
好了,現在基本算是找到菜單和權限js擷取的地方了,一般系統裡面,權限是依賴于菜單和菜單按鈕的,是以我們先不管權限,先把菜單做成動态加載的
從await _navigationScriptManager.GetScriptAsync()開始,一路F12,大概流程是
到這裡之後基本就到底了,我們看看NavigationManager的内容
這個類裡面就隻有屬性、需要注入的接口聲明、非靜态構造函數、初始化方法,我們到這裡需要關注的是Menus這個屬性,這個屬性似乎将會包含我們需要生成的菜單内容
這裡是對Menus的指派,執行個體化了一個Dictionary,前面的不用看,主要是看标紅的這句話,從new LocalizableString("MainMenu", AbpConsts.LocalizationSourceName)裡面擷取到值
好了現在基本找到地方了,我們不知道LocalizableString是什麼意思,但是我們可以百度一波
LocalizableString("Questions", "") 如果本地找不到資源,會報300
大概的意思是通過new LocalizableString,我們可以在本地化來源為AbpConsts.LocalizationSourceName的string裡面尋找到Key為MainMenu的value(了解不對請噴)
現在需要去找到那個地方對MainMenu進行了本地化操作,一般來說這個事情都是在程式加載的時候進行的,先對MainMenu進行讀取,儲存到本地,然後在_navigationScriptManager讀取,傳輸給前台
似乎不好找了,但是我們發現有一個類型MenuDefinition,F12一下,可以發現寶藏
找到了菜單的類型了,那麼我們去找儲存的地方就好找了,我們其實可以根據AddItem這個方法去找,去檢視哪個地方引用了
AddItem方法添加的是MenuItemDefinition類型的變量,那我們現在退出abp源碼,去我們的AbpLearn項目中去全局搜尋一下
看來是同一個AbpLearnNavigationProvider類裡面,輕按兩下過去看一下
好了,現在我們找到菜單定義的地方了,那麼我們如何去做動态菜單哪?
首先我們想一下需要什麼樣的動态菜單?
1.從資料庫加載,不從資料庫加載怎麼叫動态
2.可以根據不同Host(管理者)和Tenant(租戶)加載不同的菜單,不可能管理者和租戶看到的菜單全是一個樣子的吧!
3.可以根據不同的角色或者使用者加載不同的菜單(這個就牽扯到權限了,比如誰可以看到什麼,不可以看到什麼)
4.權限、按鈕最好和菜單相綁定,這樣便于控制
......
根據以上幾點,我們可以确定
1.必須要在使用者登入之後加載出來的菜單才能符合條件
2.菜單需要建一個表(因為abp預設沒有單獨的菜單表),來進行存放
3.字段需要包含:菜單名,菜單與權限對應的名稱(用于動态權限),菜單對應的Url,Icon,級聯父Id,是否啟用,排序,租戶Id
4.需要對菜單進行編輯時,因為牽扯到多租戶,我們需要對多租戶定義一個标準的菜單,在添加租戶時,自動将标準菜單複制儲存一份到新租戶中,是以我們需要對于菜單的進行區分,一般來說Host對應的資料行TenantId(int)都為null,我們可以将标準菜單的TenantId标為-1,已經配置設定儲存的菜單TenantId為目前租戶Id,這樣便于區分和查詢
好了,讓我們開始寫動态菜單吧