原創|行業資訊|編輯:龔雪|2013-11-13 10:45:38.000|閱讀 200 次
概述:本文舉例闡述了如何在模型和控制器之間使用ViewModel。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
在企業應用開發場景,我們也許需要聚集一些模型/數據來源并將其呈現為一個整體控制器。簡單起見,我們拿個需要輸入新學生姓名、年級、州(如圖一)的例子來說。
年級為A、B和C,但如果我們能夠讓這些年級顯示為第一類、第二類、第三類,而非ABC,那或許會頗有意義。因此在UI中,我們需要顯示第一二三類,但當保存數據是,我們需要在DB中保存相應的值,這同樣適用于“州”。當用戶點擊“州”下拉選擇圖標時,州列表豁然出現并展示所有州。當選中一個州時,它被顯示于UI中,但當保存到DB時,代碼名稱是諸如“Ca”代表“加利福尼亞”這樣保存的,如圖二所示。

圖一:用來輸入新生信息的表單。

圖二:當點擊州下來菜單時,如圖菜單出現。
ViewModel(視圖模型)的魔力:ViewModel允許你從一個或更多的數據模型/來源塑造多個實體到單個對象,優化了消耗和渲染。
圖三就表明了ViewModel的理念:

圖三:StudentViewModel集合了不同的模型和數據來源,提供信息給視圖作為單個實體。
ViewModel的目的是將渲染單個對象的視圖,緩解對UI邏輯代碼的需求(原本是必需)。這意味著視圖唯一的責任就是渲染該單個ViewModel對象,在一個更干凈的關注點分離予以幫助。關注點是應用程序獨特的一方面,它們有著特別的目的,而保持這些方面分離意味著你的應用程序更為有組織,代碼更為聚焦。將數據操作代碼置于其本身的位置,遠離視圖和控制器,增強關注點分離。在MVC中使用ViewModel將把你帶向更加簡單的可維護、可測試代碼。
現在我們來我們創建數據來源。第一個是年級,代碼如下。年級類是一個簡單的Dictionary對象包含兩類參數。類還包括Dictionary中所有成員的定義(如年級數據)。年級類唯一的屬性就是顯示列為清單的年級。GradeSelectList屬性中的Dictionary<string, string>類相應地映射著年級縮寫及年級名稱。
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
};
}
數據在小清單內并很少更改,如Grades,StatesDictionary類,存在于應用程序的所有類型中。
創建模型
現在我們需要一個模型來采集學生姓名、年級以及他/她來自哪個州(如圖一所示)。StudentModels類定義捕捉這些特征于簡單的數據結構中。我們現在創建一個如下的StudentModels。在Models文件夾下創建一個文件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; }
}
}
創建ViewModel
因為數據來自需要被展示在視圖中的不同來源,如果你使用ViewModel,代碼和維護將會很簡單,ViewModels只是一個類。馬上開始,創建一個新的文件夾命名為ViewModels并在其中添加一個新的代碼文件StudentViewModel.cs。要創建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();
}
}
}
創建控制器
在創建ViewModel之后,下一步就是在控制器中例示并將其返回到視圖。我們是在這個新的MVC4上做R&D(研發)因此你將看到一些亂碼。
如下代碼創建一個控制器傳送ViewModel到視圖,而我們關注的代碼是公共的ActionResult StudentInfo(),這在應用程序激活時被執行。
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視圖中創建HTML5 Mobile Form
在Visual Studio 2010中,點擊項目并新增Item命令以創建StudentInfo.cshtml。在視圖內,各種ASP.NET MVC 4 HTML Helpers通過渲染它們映射于ViewModel的數據類型的最適合的HTML元素來呈現StudentViewModel組件。比如, 年級渲染為一個HTML下拉菜單由此用戶可以輕易選中一個項目,而非手動進入之。
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>
}
下載源代碼請點擊在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 }
);
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉載自:慧都控件網