這是知識星球內的一個網友提出的,按理說ASP.NET MVC中一個視圖只能綁定一個模型(Model),在視圖頂部標識以下:html
@model IEnumerable<FineUICore.Examples.Areas.DataModel.Models.Student>
視圖中能夠表格列可使用RenderFieldFor來綁定:mvc
@(F.Grid().IsFluid(true).CssClass("blockpanel").Title("表格").ShowHeader(true).ShowBorder(true).ID("Grid1").DataIDField("Id").DataTextField("Name")
.Columns(
F.RowNumberField(),
F.RenderFieldFor(m => m.Name),
F.RenderFieldFor(m => m.Gender).RendererFunction("renderGender").Width(80),
F.RenderFieldFor(m => m.EntranceYear),
F.RenderCheckFieldFor(m => m.AtSchool).RenderAsStaticField(true),
F.RenderFieldFor(m => m.Major).RendererFunction("renderMajor").ExpandUnusedSpace(true),
F.RenderFieldFor(m => m.Group).RendererFunction("renderGroup").Width(80),
F.RenderFieldFor(m => m.EntranceDate)
).DataSource(Model)
)
使用 RenderFieldFor 而不是 RenderField 列類型,好處是不須要書寫每一個列屬性,FineUIMvc會查看模型屬性的註解並自動完成屬性賦值工做:ui
做爲對比,咱們看下使用 RenderField 時視圖的標籤訂義:spa
問題是,若是頁面上有多個表格須要綁定多個模型,該怎麼辦呢?code
拋開表格的數據綁定不談,若是想向視圖中傳遞多個數據,能夠把一個做爲模型對象傳入,其餘的做爲ViewBag傳入。orm
可是這個常看法決方法不適用於表格和表格的 RenderFieldFor 列,由於這個列是和視圖模型密切相關的,在VS的智能提示幫助下,咱們很容易發現這種關係:htm
能夠看到傳入 RenderFieldFor 的 lambda表達式左側會被識別爲模型的一部分,也就是說使用 RenderFieldFor 時模型類必須是 IEnumerable<> 泛型纔對。對象
而一個視圖不可能傳入多個模型對象。blog
若是能將 模型和表格 綁定到一塊,相似 ASP.NET WebForms 中的用戶控件(UserControl),而後在主視圖中引入這些綁定好的塊豈不是很好?get
其實ASP.NET MVC中有相似的解決方法,只不過不叫用戶控件,而稱爲分部視圖(PartialView),下面咱們就用分部視圖來實現上述功能。
1. 模型類(Student)上面已經介紹過了
2. 控制器,返回包含兩個對象元組對象
public IActionResult Index() { var students = StudentHelper.GetSimpleStudentList(); var model = new Tuple<IEnumerable<Student>, IEnumerable<Student>>(students.Where(m => m.AtSchool), students.Where(m => !m.AtSchool)); return View(model); }
3. 主視圖
@{ var F = Html.F(); } @using FineUICore.Examples.Areas.DataModel.Models; @model Tuple<IEnumerable<Student>, IEnumerable<Student>> @section body { @(Html.Partial("PartialGrid", Model.Item1, new ViewDataDictionary(ViewData) { { "__Title", "表格一(在校生)" } })) <br /> @(Html.Partial("PartialGrid", Model.Item2, new ViewDataDictionary(ViewData) { { "__Title", "表格一(畢業生)" } })) }
注意一下幾點:
3.1 模型類型是:Tuple<IEnumerable<Student>, IEnumerable<Student>>
3.2 在視圖中能夠經過 Model.Item1 獲取元組中的第一個對象,相應的 Model.Item2 獲取第二個對象,從而省去了自定義類的麻煩
3.3 使用 Html.Partial 來渲染一個分部視圖,傳入三個參數:
----1. 分部視圖的名稱,會先在主視圖所在目錄中檢索,若是找不到會轉到 Shared 目錄檢索
----2. 傳入分部視圖的模型
----3. 額外的ViewData對象,若是須要引入多個分部視圖,能夠在爲每一個分部視圖自定義顯示數據
4. 分部視圖(PartialGrid.cshtml)
@{ var F = Html.F(); } @model IEnumerable<FineUICore.Examples.Areas.DataModel.Models.Student> @{ var __Title = ViewData["__Title"].ToString(); } @(F.Grid().IsFluid(true).CssClass("blockpanel").Title(__Title).ShowHeader(true).ShowBorder(true).DataIDField("Id").DataTextField("Name") .Columns( F.RowNumberField(), F.RenderFieldFor(m => m.Name), F.RenderFieldFor(m => m.Gender).RendererFunction("renderGender").Width(80), F.RenderFieldFor(m => m.EntranceYear), F.RenderCheckFieldFor(m => m.AtSchool).RenderAsStaticField(true), F.RenderFieldFor(m => m.Major).RendererFunction("renderMajor").ExpandUnusedSpace(true), F.RenderFieldFor(m => m.Group).RendererFunction("renderGroup").Width(80), F.RenderFieldFor(m => m.EntranceDate) ).DataSource(Model) )
首先從 ViewData 獲取參數 __Title,而後在表格初始化時傳入 .Title(__Title)。
須要注意的一點,這裏不能將Grid的ID屬性設爲固定值,由於頁面上可能會屢次渲染此分部視圖,好比下面的代碼:
@(F.Grid().ID("Grid1").IsFluid(true).CssClass("blockpanel").Title(__Title).
若是頁面上引入兩次本分部視圖,則頁面上會有兩個ID爲 Grid1 的表格對象,這就搞錯了!
解決辦法有兩個:
1. 不設置 Grid 的 ID 屬性,這樣 FineUIMvc 會在頁面範圍內自動生成一個不重複的
2. 在主視圖調用 Html.Partial 時,傳入一個相似 __Prefix 的屬性,而後在分部視圖中爲表格ID加上這個前綴,有沒有一種ASP.NET WebForms的感受:
主視圖:
@(Html.Partial("PartialGrid", Model.Item1, new ViewDataDictionary(ViewData) { { "__Prefix", "Connector1" }, { "__Title", "表格一(在校生)" } })) <br /> @(Html.Partial("PartialGrid", Model.Item2, new ViewDataDictionary(ViewData) { { "__Title", "Connector2" }, { "__Title", "表格一(畢業生)" } }))
分部視圖:
@(F.Grid().ID(ViewData["__Prefix"].ToString() + "_Grid1").IsFluid(true).CssClass("blockpanel").Title(__Title).
最終頁面的顯示效果:
這篇文章講解了如何在ASP.NET MVC視圖中綁定多個模型,解決之道就是分部視圖(PartialView),分部視圖相似於ASP.NET WebForms中的用戶控件,而不一樣之處在於分部視圖不會給內部的控件ID加上所在的層次結構,所以若是一個頁面中屢次引入同一個分部視圖就須要注意ID是否重複的問題了。
這個示例會更新到 FineUIMvc v5.3.0 版本中,查看 FineUIMvc 在線示例:http://mvc.fineui.com/