上一節課我們將model的資料傳給了view
那這節我們再改用ViewModel傳資料給demo的view
先建一個ViewModels的資料夾,並新增一個DemoViewModel.cs
裡面我們先用跟TOPMenu一樣的欄位
namespace Kcg.ViewModels
{
public class DemoIndexViewModel
{
public Guid TOPMenuId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Icon { get; set; }
public int Orders { get; set; }
}
}
然後再改一下DemoController中的Index程式碼
public IActionResult Index()
{
DemoIndexViewModel model = _kcgContext.TOPMenu.Select(a => new DemoIndexViewModel
{
Icon = a.Icon,
Name = a.Name,
Orders = a.Orders,
TOPMenuId = a.TOPMenuId,
Url = a.Url
}).FirstOrDefault();
return View(model);
}
最後Index.cshtml也要修改一下mode的類別為DemoViewModel
@model DemoIndexViewModel
這是從Controller過來的Model資料
<br />
Name:@Model.Name
<br />
Icon:@Model.Icon
<br />
Url:@Model.Url
之後執行看看有沒有成功,如下
這時候應該有人有疑問,那跟上一節課直接丟TOPMenu的model過來有什麼差別?
沒錯,基本上是完全一模一樣的行為,那為什麼還要改用ViewModel呢?主要有幾個原因
- 命名原則:就是一個對應,像我們看到DemoIndexViewModel從名字就可以知道這個是demo/view這一頁的資料類別,提高可讀和維護性
- 關注點分離:簡單來說我們一看ViewModel結尾的檔案,就知道他是在做這件事
另外,通常我們一頁可能不只有某個資料表的資料,還有可能有很多其他輔助需要的資訊一起傳過去給view
這邊我們就來實際再改一下原來的DemoIndexViewModel程式碼
public class DemoIndexViewModel
{
public List<TOPMenu> TOPMenu { get; set; }
public List<string> 科室清單 { get; set; }
public string 可能的其他資料 { get; set; }
}
上面就是我們DemoIndexViewModel所需要的資料,不僅僅需要TOPMenu或許還會需要科室的清單,或其他資料
所以我們的View幾乎不可能只需要某個資料表的資料而已,因此大多情況都會特別建立一個對應的ViewModel,對日後也很好維護
那我們這邊再改寫一下DemoController的Index的程式碼
public IActionResult Index()
{
DemoIndexViewModel model = new DemoIndexViewModel();
model.TOPMenu = _kcgContext.TOPMenu.ToList();
model.科室清單 = new List<string> { "科室1", "科室2", "科室3" };
model.可能的其他資料 = "其他資料";
return View(model);
}
前面的Index也修改一下
@model DemoIndexViewModel
這是從Controller過來的Model資料
<br />
Name:@Model.TOPMenu[0].Name
<br />
Icon:@Model.TOPMenu[0].Icon
<br />
Url:@Model.TOPMenu[0].Url
@foreach (var temp in Model.科室清單)
{
<div>@temp</div>
}
@Model.可能的其他資料;
那來看看最後顯示結果,如下
結論,其實說穿了ViewModel並沒有什麼特殊功能,他就是一個普通的class,也沒繼承任何東西,算是設計模式的一種
你當然可以用其他方式取代或不使用,只是這是一種主流的用法,你這樣用對其他人如果接手的話會更好維護
大家心中都知道ViewModel是在做什麼的,自然就不用多花時間去研究你到底在寫什麼,一看就大概知道
總之,就是一個View通常會有一個對應的ViewModel