MVC 中的 View 就與前端密切相關,這個章節要來介紹 ASP.NET MVC 中的 View
透過樣板引擎(template engine),將轉換成 HTML 的頁面,回傳給瀏覽器供顯示
View 的類型
View 的副檔名是 .cshtml
(或 .vbhtml
)
View 的種類可分為幾種:
- View:action 回傳 ViewResult
- Partial View:action 回傳 PartialViewResult,習慣上的命名會是底線開頭、partial 結尾
- Layout:一個組成頁面的共用樣板,像是 Header、Menu、Footer 會在其中,container 元件的概念。利用
RenderSection
、RenderBody
等方法,在 layout 裡面插入 slot 已供使用的時候,置入想要的 Partial View template - Template:可以說是比 Partial View 更小的規模。分為 DisplayTemplate 與 EditorTemplate 兩種類型,前者用於檢視、後者用於編輯的頁面
獲得資料的方法
View 經常是一個被動的角色,Controller 執行完畢,準備好提供給 View 的 Model,調用特定的 View 以 HTML 解釋這份資料
方式 | 優點 | 缺點 |
---|---|---|
Model | 強型別,得以藉編譯期間進行型別檢查 | 當以 string 型別作為 View Model 時會有一點點小麻煩 |
ViewData | 不需要建立 View Model 類別即可傳遞資料 | 弱型別,無編譯期間型別檢查 |
ViewBag | 不需要建立 View Model 類別即可傳遞資料 | 弱型別,無編譯期間型別檢查 |
TempData | 不需要建立 View Model 類別即可傳遞資料,可以跨 Action 傳遞 | 弱型別,無編譯期間型別檢查 |
View Engine 概觀
View Engine 隱藏在 Action 與 View 之間,當回傳 ViewResult(或 PartialViewResult)後,ActionInvoker 呼叫 ExecuteResult 方法,啟動 View Engine 來工作
View Engine 有兩種實作,WebForm View Engine 與 Razor View Engine,在 Controller 的章節已有提到
除了上述兩種內建的 View Engine 之外,網路上也有開源社群提供的多種 View Engine,像是:Spark View Engine、JsViewEngine、FreeMarker.NET、BLADE View Engine、NHaml、Aurora View Engine、XsltViewEngine⋯⋯ 等
使用第三方的 View Engine,除了用 NuGet 安裝第三方套件之外,還要在 Global.asax
的 Application_Start 方法底下註冊後方可使用
Razor 語法
這裡列出 Razor 的一些基本語法與書中範例,同時對照著前端三大框架的相對應寫法
程式碼區塊 Code Block
@{
int val = 10;
string message = "hello";
}
React
在 function 裡面,與 jsx 分離
Vue
在 <script>
裡面,與 <template>
分離
Angular
在 @component class
裡面,與 html 分離
陳述式 Expression
<span>@message</span>
<span>@Html.Raw(message)</span>
React
<span>{message}</span>
Vue, Angular
<span>{{message}}</span>
結合程式與標記語言
@foreach(var item in items)
{
<span>@item.Property</span>
}
React
{items.map((item) => <span key={item.property}>{item.property}</span>)}
Vue
<span v-for="item in items">{{ item.property }}</span>
Angular
<span *ngFor="let item of items">{{ item.property }}</span>
混合程式與文字
// 1
@if(condition)
{
<text>Plain text</text> @condition
}
// 2
Hello, my name is @name
//3
@if(condition)
{
@:Plain text @condition
}
React
{condition && <p>hello world</p>}
Vue
<p v-if="condition">hello world</p>
Angular
<p *ngIf="condition">hello world</p>
using 區塊
@using(Html.BeginForm())
{
<input type="submit" value="Submit" />
}
hi someone@microsoft.com
@ 符號(跳脫字元)
<div>show @@ mark on razor template</div>
三大框架的部分,因為語法的緣故,比較要注意的大概是 >
、<
、{
、}
這四種符號的跳脫方式
React
在 jsx 中需要跳脫的字元,像是:>
、<
、{
、}
,可轉換成 HTML code 的寫法:>
、<
、{
、}
,或用括號包成字串的方式處理
// error
<div><></div>
// solution
<div>{"<>"}</div>
<div><></div>
// error
<div>{}</div>
<div>{{}}</div>
// solution
<div>{}</div>
<div>{"{{}}"}</div>
// error
<div>{{greeting}}</div>
// solution
<div>{`{${greeting}}`}</div>
<div>{{greeting}}</div>
Vue
HTML code 在使用 >
、<
沒什麼問題,但兩層的 {
、}
(也就是 {{ }}
)扔會出現錯誤,
簡單的做法就是用 <span>
包起來:
<!-- error -->
<div><></div>
<div>{{"<>"}}</div>
<!-- solution -->
<div><></div>
<!-- ok -->
<div>{}</div>
<div>{{}}</div>
<!-- error -->
<div>{{{{greeting}}}}</div>
<div>{{`{{${greeting}}}`}}</div>
<div>{{`{{${greeting}}}`}}</div>
<div>{{{{greeting}}}}</div>
<!-- solution -->
<div><span>{{</span>{{greeting}}<span>}}</span></div>
Angular
Angular 可以直接在 template 使用 >
、<
,當然 >
、<
也是沒問題;
括號的部分同樣用字串來處理;變數與括號的混合,則同 Vue 用 <span>
隔開
<!-- ok -->
<div><></div>
<!-- error -->
<div>{}</div>
<div>{{}}</div>
<!-- solution -->
<div>{{"{}"}}</div>
<div>{{"{{}}"}}</div>
<!-- error -->
<div>{{{greeting}}}</div>
<div>{{`{{${greeting}}}`}}</div>
<div>{{`{${greeting}}`}}</div>
<div>{{{greeting}}}</div>
<div><span>{</span>{{greeting}}<span>}</span></div>
<!-- solution -->
<div><span>{</span>{{greeting}}<span>}</span></div>
<div><span>{{</span>{{greeting}}<span>}}</span></div>
註解
@*
多行註解
⋯⋯
*@
@* 單行註解 *@
React
{/* hello this is comment */}
{/*
comment 1
comment 2
...
*/}
Vue, Angular
<template>
<!-- this is comment -->
</template>
Func 委派
@{
Func<string, object> strongify = @<strong>@item</strong>
}
@strongify("John")
React
const strongify = (text) => <strong>{text}</strong>;
{ strongify("John")}
用傳入 props 的方式實作
Vue, Angular
同樣利用 component 傳入 props 的方式來實作
Helpers
主要有三種 Helper 可以使用:UrlHelper、HtmlHelper、AjaxHelper, 在 View 中,分別使用 Url、Html、Ajax 分別取得這三種 Helper 的執行個體
UrlHelper
- Action
- RouteUrl
- HttpRouteUrl
- Content
- Encode
- IsLocalUrl
最常使用的,大概是 Url.Action 了,用來加在 <a>
的 href 上
HtmlHelper
在 View 中最常見的 Helper,可大致分為三類:一般類、表單類、功能類
HtmlHelper 有很大一部分的方法,是倚賴 Model 與 Lambda Expression
一般類
- Action, RenderAction
- Partial, RenderPartial:用於插入 Partial View,佷常使用
- ActionLink
- RouteLink
- AntiForgeryToken
- Encode
- Raw
表單類
- BeginForm:製作一個
<form>
的表單區塊 - BeginRouteForm
- EndForm
- TextBox, TextBoxFor
- Hidden, HiddenFor
- Password, PasswordFor
- CheckBox, CheckBoxFor
- RadioButton, RadioButtonFor
- DropDownList, DropDownListFor
- EnumDropDownListFor
- ListBox, ListBoxFor
- EditBox, EditBoxFor
- Label, LabelFor
- DisplayName, DisplayNameFor
- DisplayText, DisplayTextFor
- Display, DisplayFor
- DisplayForModel
- Editor, EditorFor
- EditorForModel
- ValidationMessage, ValidationMessageFor
- ValidationSummary
這一類幾乎都是會轉換成表單類 HTML 的 Helper 方法
功能類
- AttributeEncode
- Id, IdFor
- Name, NameFor
AjaxHelper
AjaxHelper 在 HTML 標籤上添加 data-*
屬性,供 unobtrusive 使用,透過 jquery.unobtrusive-ajax.js 讓 HTML 標籤擁有 AJAX 的能力