原創(chuàng)|行業(yè)資訊|編輯:龔雪|2013-11-13 10:45:38.000|閱讀 196 次
概述:本文舉例闡述了如何在模型和控制器之間使用ViewModel。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在企業(yè)應(yīng)用開發(fā)場(chǎng)景,我們也許需要聚集一些模型/數(shù)據(jù)來源并將其呈現(xiàn)為一個(gè)整體控制器。簡(jiǎn)單起見,我們拿個(gè)需要輸入新學(xué)生姓名、年級(jí)、州(如圖一)的例子來說。
年級(jí)為A、B和C,但如果我們能夠讓這些年級(jí)顯示為第一類、第二類、第三類,而非ABC,那或許會(huì)頗有意義。因此在UI中,我們需要顯示第一二三類,但當(dāng)保存數(shù)據(jù)是,我們需要在DB中保存相應(yīng)的值,這同樣適用于“州”。當(dāng)用戶點(diǎn)擊“州”下拉選擇圖標(biāo)時(shí),州列表豁然出現(xiàn)并展示所有州。當(dāng)選中一個(gè)州時(shí),它被顯示于UI中,但當(dāng)保存到DB時(shí),代碼名稱是諸如“Ca”代表“加利福尼亞”這樣保存的,如圖二所示。
圖一:用來輸入新生信息的表單。
圖二:當(dāng)點(diǎn)擊州下來菜單時(shí),如圖菜單出現(xiàn)。
ViewModel(視圖模型)的魔力:ViewModel允許你從一個(gè)或更多的數(shù)據(jù)模型/來源塑造多個(gè)實(shí)體到單個(gè)對(duì)象,優(yōu)化了消耗和渲染。
圖三就表明了ViewModel的理念:
圖三:StudentViewModel集合了不同的模型和數(shù)據(jù)來源,提供信息給視圖作為單個(gè)實(shí)體。
ViewModel的目的是將渲染單個(gè)對(duì)象的視圖,緩解對(duì)UI邏輯代碼的需求(原本是必需)。這意味著視圖唯一的責(zé)任就是渲染該單個(gè)ViewModel對(duì)象,在一個(gè)更干凈的關(guān)注點(diǎn)分離予以幫助。關(guān)注點(diǎn)是應(yīng)用程序獨(dú)特的一方面,它們有著特別的目的,而保持這些方面分離意味著你的應(yīng)用程序更為有組織,代碼更為聚焦。將數(shù)據(jù)操作代碼置于其本身的位置,遠(yuǎn)離視圖和控制器,增強(qiáng)關(guān)注點(diǎn)分離。在MVC中使用ViewModel將把你帶向更加簡(jiǎn)單的可維護(hù)、可測(cè)試代碼。
現(xiàn)在我們來我們創(chuàng)建數(shù)據(jù)來源。第一個(gè)是年級(jí),代碼如下。年級(jí)類是一個(gè)簡(jiǎn)單的Dictionary對(duì)象包含兩類參數(shù)。類還包括Dictionary中所有成員的定義(如年級(jí)數(shù)據(jù))。年級(jí)類唯一的屬性就是顯示列為清單的年級(jí)。GradeSelectList屬性中的Dictionary<string, string>類相應(yīng)地映射著年級(jí)縮寫及年級(jí)名稱。
public class Grades { public static SelectList GradeSelectList { get { return new SelectList(GradeDictionary, "Value", "Key"); } } public static readonly IDictionary<string, string> GradeDictionary = new Dictionary<string, string> { {"Choose…",""} , { "First Class", "A" } , { "Second Class", "B" } , { "Third Class", "c" } }; }
同樣的login用于“州”。StatesDictionary的代碼如下:
public class StatesDictionary { public static SelectList StateSelectList { get { return new SelectList(StateDictionary, "Value", "Key"); } } public static readonly IDictionary<string, string> StateDictionary = new Dictionary<string, string> { {"Choose…",""} , { "Alabama", "AL" } , { "Alaska", "AK" } , { "Arizona", "AZ" } , { "Arkansas", "AR" } , { "California", "CA" } , { "Colorado", "CO" } , { "Connecticut", "CT" } , { "Delaware", "DE" } , { "District of Columbia", "DC" } , { "Florida", "FL" } , { "Georgia", "GA" } , { "Hawaii", "HI" } , { "Idaho", "ID" } , { "Illinois", "IL" } , { "Indiana", "IN" } , { "Iowa", "IA" } , { "Kansas", "KS" } , { "Kentucky", "KY" } , { "Louisiana", "LA" } , { "Maine", "ME" } , { "Maryland", "MD" } , { "Massachusetts", "MA" } , { "Michigan", "MI" } , { "Minnesota", "MN" } , { "Mississippi", "MS" } , { "Missouri", "MO" } , { "Montana", "MT" } , { "Nebraska", "NE" } , { "Nevada", "NV" } , { "New Hampshire", "NH" } , { "New Jersey", "NJ" } , { "New Mexico", "NM" } , { "New York", "NY" } , { "North Carolina", "NC" } , { "North Dakota", "ND" } , { "Ohio", "OH" } , { "Oklahoma", "OK" } , { "Oregon", "OR" } , { "Pennsylvania", "PA" } , { "Rhode Island", "RI" } , { "South Carolina", "SC" } , { "South Dakota", "SD" } , { "Tennessee", "TN" } , { "Texas", "TX" } , { "Utah", "UT" } , { "Vermont", "VT" } , { "Virginia", "VA" } , { "Washington", "WA" } , { "West Virginia", "WV" } , { "Wisconsin", "WI" } , { "Wyoming", "WY" } // more states }; }
數(shù)據(jù)在小清單內(nèi)并很少更改,如Grades,StatesDictionary類,存在于應(yīng)用程序的所有類型中。
創(chuàng)建模型
現(xiàn)在我們需要一個(gè)模型來采集學(xué)生姓名、年級(jí)以及他/她來自哪個(gè)州(如圖一所示)。StudentModels類定義捕捉這些特征于簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu)中。我們現(xiàn)在創(chuàng)建一個(gè)如下的StudentModels。在Models文件夾下創(chuàng)建一個(gè)文件StudentModels.cs并添加如下代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; namespace TagStatus.Models { public class StudentModels { [Display(Name = "Student Name here")] [Required()] public string StudentName { get; set; } public string Grade { get; set; } public string State { get; set; } } }
創(chuàng)建ViewModel
因?yàn)閿?shù)據(jù)來自需要被展示在視圖中的不同來源,如果你使用ViewModel,代碼和維護(hù)將會(huì)很簡(jiǎn)單,ViewModels只是一個(gè)類。馬上開始,創(chuàng)建一個(gè)新的文件夾命名為ViewModels并在其中添加一個(gè)新的代碼文件StudentViewModel.cs。要?jiǎng)?chuàng)建StudentViewModel,添加StudentModels、Grades和StatesDictionary作為來自StudentViewModel的屬性。在如下源代碼中,StudentViewModel類包含新定義的屬性。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using TagStatus.Models; namespace TagStatus.ViewModels { public class StudentViewModel { public StudentModels Student { get; set; } public Grades Grades { get; set; } public StatesDictionary States { get; set; } public StudentViewModel(StudentModels student) { Student = student; Grades = new Grades(); States = new StatesDictionary(); } public StudentViewModel() { Student = new StudentModels(); ; Grades = new Grades(); States = new StatesDictionary(); } } }
創(chuàng)建控制器
在創(chuàng)建ViewModel之后,下一步就是在控制器中例示并將其返回到視圖。我們是在這個(gè)新的MVC4上做R&D(研發(fā))因此你將看到一些亂碼。
如下代碼創(chuàng)建一個(gè)控制器傳送ViewModel到視圖,而我們關(guān)注的代碼是公共的ActionResult StudentInfo(),這在應(yīng)用程序激活時(shí)被執(zhí)行。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using TagStatus.Models; using TagStatus.ViewModels; namespace TagStatus.Controllers { public class StudentController : Controller { //public string StudentName { get; set; } //public int Grade { get; set; } // // GET: /Student/ public ActionResult Index() { StudentModels stdm = new StudentModels(); StudentViewModel stdvm = new StudentViewModel(stdm); return View(stdvm); } //[AllowAnonymous] //public ActionResult StudentInfo() //{ // return View(); //} [AllowAnonymous] [HttpPost] public ActionResult StudentInfo(StudentModels model) { if (ModelState.IsValid) { model.StudentName = model.State; } return View(model); } [AllowAnonymous] public ActionResult StudentInfo() { StudentViewModel model = new StudentViewModel(); //model.StudentName = model.State; return View(model); } } }
在ASP.NET MVC 4視圖中創(chuàng)建HTML5 Mobile Form
在Visual Studio 2010中,點(diǎn)擊項(xiàng)目并新增Item命令以創(chuàng)建StudentInfo.cshtml。在視圖內(nèi),各種ASP.NET MVC 4 HTML Helpers通過渲染它們映射于ViewModel的數(shù)據(jù)類型的最適合的HTML元素來呈現(xiàn)StudentViewModel組件。比如, 年級(jí)渲染為一個(gè)HTML下拉菜單由此用戶可以輕易選中一個(gè)項(xiàng)目,而非手動(dòng)進(jìn)入之。
StudentInfo.cshtml代碼如下:
@model TagStatus.ViewModels.StudentViewModel @{ ViewBag.Title = "Student Info"; } <h2> New Student </h2> @using (Html.BeginForm("Results","Home")) { @Html.ValidationSummary(true) <fieldset> <legend>Enter Student Information!</legend> <div class="editor-label"> @Html.LabelFor(model => model.Student.StudentName) </div> <div class="editor-field"> @Html.TextBoxFor(Model => Model.Student.StudentName) @Html.ValidationMessageFor(Model => Model.Student.StudentName) </div> <div class="editor-label"> @Html.LabelFor(model => model.Student.Grade) </div> <div class="editor-field"> @Html.DropDownListFor(Model => Model.Student.Grade, Grades.GradeSelectList) </div> <div class="editor-label"> @Html.LabelFor(model => model.Student.State) </div> <div class="editor-field"> @Html.DropDownListFor(Model => Model.Student.State, StatesDictionary.StateSelectList) </div> <p> <input type="submit" value="Save" /> </p> </fieldset> }
下載源代碼請(qǐng)點(diǎn)擊在Global.asax文件做如下改變:
routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", //defaults: new { controller = "Tag", action = "Lookup", id = UrlParameter.Optional } defaults: new { controller = "Student", action = "StudentInfo", id = UrlParameter.Optional } //defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } );
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都控件網(wǎng)