1. 程式人生 > >如何在FineUIMvc(ASP.NET MVC)檢視中繫結多個模型?

如何在FineUIMvc(ASP.NET MVC)檢視中繫結多個模型?

起因

這是知識星球內的一個網友提出的,按理說ASP.NET MVC中一個檢視只能繫結一個模型(Model),在檢視頂部標識如下:

@model IEnumerable<FineUICore.Examples.Areas.DataModel.Models.Student>

檢視中可以表格列可以使用RenderFieldFor來繫結:

@(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會檢視模型屬性的註解並自動完成屬性賦值工作:

作為對比,我們看下使用 RenderField 時檢視的標籤定義:

問題是,如果頁面上有多個表格需要繫結多個模型,該怎麼辦呢?

探索之路

拋開表格的資料繫結不談,如果想向檢視中傳遞多個數據,可以把一個作為模型物件傳入,其他的作為ViewBag傳入。

但是這個常見解決方法不適用於表格和表格的 RenderFieldFor 列,因為這個列是和檢視模型密切相關的,在VS的智慧提示幫助下,我們很容易發現這種關係:

可以看到傳入 RenderFieldFor 的 lambda表示式左側會被識別為模型的一部分,也就是說使用 RenderFieldFor 時模型類必須是 IEnumerable<> 泛型才對。

而一個檢視不可能傳入多個模型物件。

如果能將 模型和表格 繫結到一塊,類似 ASP.NET WebForms 中的使用者控制元件(UserControl),然後在主檢視中引入這些繫結好的塊豈不是很好?

其實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/

相關推薦

如何在FineUIMvcASP.NET MVC檢視模型

起因 這是知識星球內的一個網友提出的,按理說ASP.NET MVC中一個檢視只能繫結一個模型(Model),在檢視頂部標識如下: @model IEnumerable<FineUICore.Examples.Areas.DataModel.Models.Student> 檢視中可

如何在FineUIMvcASP.NET MVC顯示覆雜的表格列資料列表和物件

起源 最初,這個問題是知識星球內的一個網友提出的,如何在FineUIMvc中展現複雜的列資料? 在FineUIPro中,我們都知道有一個 TemplateField 模板列可以使用,我們只需要在後臺定義一個 C# 方法,就可以返回任意想要的資料。 可是在FineUIMvc中沒有這麼個列型別,那又

用EasyUI-DataGrid實現列表批量刪除的功能ASP.NET/MVC

1、前端程式碼:首先給列表新增多選框。注意:當singleSelect的屬性值為false時,才能實現多選功能;當checkbox屬性值為true選擇行勾選,false選擇行不勾選。 <table id="dataGrid" class="easyui-datagrid" title=""

如何給DropDownList控制元件設定樣式ASP.NET MVC

應學校領導要求,要給後臺管理系統新增一個搜尋功能,提供可選擇選項。我選擇使用DropDownList去實現,熟悉.net控制元件的都知道,DropDownList的樣子非常醜,不論是邊框長寬還是裡面的下拉三角形,都給人很不舒服的感覺,作為一個愛美的女生,怎麼可能容忍呢!!

Spring與Web框架例如Spring MVC漫談——關於Spring對於Web框架的支援

  在看Spring MVC的官方文件時,最後一章是關於Spring對於其它Web框架的支援(如JSF,Apache Struts 2.x,Tapestry 5.x),當然Spring自己的MVC框架Spring MVC就不用多說了。   這裡並不想討論其它的Web框架,而是記錄下這章開頭提到的關於Spri

ButterKnife之三:AdapterButterKnife核心常用功能使用替代findviewbyid,替代OnClickListener以及id監聽事件

在上一篇“ButterKnife之一:Activity中ButterKnife核心常用功能使用(替代findviewbyid,替代OnClickListener以及繫結多個id監聽事件)”中對ButterKnife已經做了相對較詳細的介紹,本篇只對Adapter中ButterKnife使用的程式

ButterKnife之二:Fragment ButterKnife核心常用功能使用替代findviewbyid,替代OnClickListener以及id監聽事件

在上一篇“ButterKnife之一:Activity中ButterKnife核心常用功能使用(替代findviewbyid,替代OnClickListener以及繫結多個id監聽事件)”中對ButterKnife已經做了相對較詳細的介紹,本篇只對Fragment 中ButterKnife使用的

ButterKnife之一:ActivityButterKnife核心常用功能使用替代findviewbyid,替代OnClickListener以及id監聽事件

ButterKnife是一個註解類,ButterKnife開源框架以其強大的view繫結和click事件處理功能,大大減少程式碼量,節省開發時間,提高開發效率,而且ButterKnife在adapter中的使用也方便的處理了adapter中ViewHodler的繫結問題,下面就學習內容做簡單記錄

ASP.NET MVC之下拉框四種方式

http://www.cnblogs.com/CreateMyself/p/5424894.html 前言 上兩節我們講了檔案上傳的問題,關於這個上傳的問題還未結束,我也在花時間做做分割大檔案處理以及顯示進度的問題,到時完成的話再發表,為了不耽誤學習MVC其他

從零開始學 Web 之 jQuery為元素相同事件,解綁事件

一、為元素繫結多個相同事件 1、方式一 $("#btn").click(function () { console.log("click1"); }).click(function () { console.log("click2"); }).cli

關於一個伺服器域名——公司是用阿里雲伺服器--是使用tomcat來

我是使用多個tomcat來新增 由於之前已經有一個tomcat,而且上面已經有了一個專案,專案使用的埠號是8080,然而瀏覽器預設的埠號是80,如果將server.xml修改了埠,那之前的專案就會出錯了,所以要繫結域名又不想更改埠號就建立多一個tomcat了 1.將tom

適合ASP.NET MVC檢視片斷快取方式:更實用的API

上一篇文章中我們提出了了片斷快取的基本方式,也就是構建HtmlHelper的擴充套件方法Cache,接受一個用於生成字串的委託物件。在快取命中時,則直接返回快取中的字串片斷,否則則使用委託生成的內容。因此,快取命中時委託的開銷便節省了下來。不過這個方法並不實用,如果您要快取大片的HTML,還需要準備一個Par

ASP.NET MVC & WebApi 實現Cors來讓Ajax可以跨域訪問 轉載

詳細 簡介 part bsp bob 打印 不能 res user 什麽是Cors? CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了

FineUIMvc v1.4.0 發布了ASP.NET MVC控件庫

ima font .com 基礎 ref baidu 捐贈 三石 全部 FineUIMvc v1.4.0 已經於 2017-06-30 發布,FineUIMvc 是基於 jQuery 的專業 ASP.NET MVC 控件庫,是我們的新產品。由於和 FineUI(專業版)共享

適合ASP.NET MVC檢視片斷快取方式:起步

說到網站效能優化,沒有什麼比“快取”更重要了。即便是某些朋友口中念念不忘的“靜態頁”,說到底也只是快取了整張頁面內容而已。但是,顯然這樣大粒度的快取策略,在如今“牽一髮而動全身”的Web 2.0站點中幾乎是無法使用的。試想,在Twitter中的某個名人被數十萬人訂閱,那麼他發一條訊息,難道此時網站要去修改數十

適合ASP.NET MVC檢視片斷快取方式:頁面輸出原則

上一篇文章裡已經把Html.Cache打造成了非常具有可用性的API,需要快取時我們只需在頁面上做一個標記即可:<% Html.Cache("cache_key", DateTime.Now.AddSeconds(10), () => { %> <% foreach (

ASP.NET MVC 學習: 檢視

用檢視呈現UI 檢視可以不包含任何應用邏輯或者資料庫檢索程式碼,所有的應用邏輯都可以在controller中進行處理。 檢視通過使用controller類在呼叫RenderView方法的時候提供檢視相關資料物件呈現UI: publicvoid Categories() {     List<C

Asp.net MVC Preview 4 使用RenderComponent

RenderComponent在Pv3及以前版本中經常用到,自從Monorails而來Component就以其方便自然而讓我很是喜歡,雖然它效能明顯不如Parse/UserControl 在pv4中要使用以下方法來呼叫元件 <%Html.RenderAction<HomeControlle

Asp.net MVC Preview 4 自定義Jquery的HtmlHelper擴充套件

using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; us

Asp.net mvc 動作方法 呼叫 另一個控制器的動作方法

public ActionResult 動作方法() { var otherController = DependencyResolver.Current.GetService<另一個控制