ASP.NET 團隊和社區在 .NET 8 繼續全力投入 Blazor,為它帶來了非常多的新特性,特別是在服務端渲染(SSR)方面,一定程度解決之前 WASM 載入慢,Server 性能不理想等局限性,也跟原來的 MVC,Razor Pages 框架在底層完成了統一。 AntDesign Blazo ...
ASP.NET 團隊和社區在 .NET 8 繼續全力投入 Blazor,為它帶來了非常多的新特性,特別是在服務端渲染(SSR)方面,一定程度解決之前 WASM 載入慢,Server 性能不理想等局限性,也跟原來的 MVC,Razor Pages 框架在底層完成了統一。
AntDesign Blazor 作為 Blazor 最受歡迎的開源組件庫之一,自然也會繼續佛系跟進。本篇主要介紹第一個在 AntDesign Blazor 上應用的 .NET 8 新特性—— CascadingModelBinder
,我利用它實現了 ReuseTabs 自 2021 年發佈兩年後,一直未支持的 Query String 屬性綁定。
ReuseTabs 是 AntDesign Blazor 在 2021 年 7 月增加的組件,也是 Blazor 目前唯一真正實現路由復用的組件。它只需在 App.razor 增加 RouteData 級聯值,就可以在任何 Blazor 項目中獨立使用(其文檔上的例子就是在官方模板上使用的),不依賴菜單配置就能夠主動識別路由,渲染頁面組件,並保持每個 Tab 頁面的狀態切換不會丟失。不像其他組件庫的實現,只能在他們指定的配套模板上才能使用…
它的實現原理也很簡單,是通過級聯的 RouteData 值,獲取需要展示的組件類型以及要綁定頁面組件的屬性值,再動態渲染組件的。但是因為在 .NET 6 加入的 Query string 屬性值綁定實現是在 RouteView 內部利用一個內部靜態方法來解析 QueryString 並傳給頁面組件的,ReuseTabs 想要支持得把代碼都抄一份。當時就覺得這樣的設計很有局限(後來就懶得了)。
直到在前段時間 .NET 官方博客中發佈的文章 ASP.NET Core 在 .NET 8 Preview 6 中的更新,裡面提到了一個特性,級聯 query string 值到 Blazor 組件,意思是不再讓Query string 值綁定局限於頁面組件了,我就像這下 ReuseTabs 缺失了兩年的功能,有希望填補了。
於是就有了今天要介紹的內容。
為了尋找官方是怎麼實現的,把 aspnetcore 倉庫源碼切換到 .NET 6 Preivew 6 的 tag 上,找到 RouteView 的源碼在RouteView.cs 中的 RenderPageWithParameters 方法,就是用於渲染頁面組件的。
於是追溯這個文件的歷史記錄,找到在這個支持服務端靜態渲染表單的 PR#47716 加入了 CascadingModelBinder,這樣就可以從 Http 請求中獲取提交的 FormData 綁定到組件中標記了 SupplyParameterFromForm 特性的模型上。
接著,在PR #48554 中使 SupplyParameterFromQuery 也能夠通過 CascadingModelBinder 傳遞了,然後把上文提到的 RouteView 中的內部類 QueryParameterValueSupplier 相關代碼刪掉了。
這簡直正中眉心,馬上我就把 RouteView 中的這段代碼複製到 ReuseTabs 中了,PRhttps://github.com/ant-design-blazor/ant-design-blazor/pull/3377,完美!
最終效果:
開心之餘,我尋思著就算是抄,也不能抄的不明不白吧,於是就順便調查了一下 CascadingModelBinder 是怎麼傳遞級聯值的。簡單一句就是 Blazor 創建了 CascadingModelBinder 組件和 CascadingModelBindingProvider 提供者來抽象和統一了級聯傳值方法。沒想到官方博客中平淡的兩句話介紹背後有這麼大的改動。詳情請關註我後面文章,另作介紹。