[筆記] ASP.NET MVC5 - Ch.8 View
MVC 中的 View 就與前端密切相關,這個章節要來介紹 ASP.NET MVC 中的 View
透過樣板引擎(template engine),將轉換成 HTML 的頁面,回傳給瀏覽器供顯示
View 的類型
Section titled “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 兩種類型,前者用於檢視、後者用於編輯的頁面
獲得資料的方法
Section titled “獲得資料的方法”View 經常是一個被動的角色,Controller 執行完畢,準備好提供給 View 的 Model,調用特定的 View 以 HTML 解釋這份資料
| 方式 | 優點 | 缺點 |
|---|---|---|
| Model | 強型別,得以藉編譯期間進行型別檢查 | 當以 string 型別作為 View Model 時會有一點點小麻煩 |
| ViewData | 不需要建立 View Model 類別即可傳遞資料 | 弱型別,無編譯期間型別檢查 |
| ViewBag | 不需要建立 View Model 類別即可傳遞資料 | 弱型別,無編譯期間型別檢查 |
| TempData | 不需要建立 View Model 類別即可傳遞資料,可以跨 Action 傳遞 | 弱型別,無編譯期間型別檢查 |
View Engine 概觀
Section titled “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 語法
Section titled “Razor 語法”這裡列出 Razor 的一些基本語法與書中範例,同時對照著前端三大框架的相對應寫法
程式碼區塊 Code Block
Section titled “程式碼區塊 Code Block”@{ int val = 10; string message = "hello";}React
在 function 裡面,與 jsx 分離
Vue
在 <script> 裡面,與 <template> 分離
Angular
在 @component class 裡面,與 html 分離
陳述式 Expression
Section titled “陳述式 Expression”<span>@message</span>
<span>@Html.Raw(message)</span>React
<span>{message}</span>Vue, Angular
<span>{{message}}</span>結合程式與標記語言
Section titled “結合程式與標記語言”@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>混合程式與文字
Section titled “混合程式與文字”// 1@if(condition){ <text>Plain text</text> @condition}
// 2Hello, 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 區塊
Section titled “using 區塊”@using(Html.BeginForm()){ <input type="submit" value="Submit" />}hi someone@microsoft.com@ 符號(跳脫字元)
Section titled “@ 符號(跳脫字元)”<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 委派
Section titled “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
Section titled “Helpers”主要有三種 Helper 可以使用:UrlHelper、HtmlHelper、AjaxHelper, 在 View 中,分別使用 Url、Html、Ajax 分別取得這三種 Helper 的執行個體
UrlHelper
Section titled “UrlHelper”- Action
- RouteUrl
- HttpRouteUrl
- Content
- Encode
- IsLocalUrl
最常使用的,大概是 Url.Action 了,用來加在 <a> 的 href 上
HtmlHelper
Section titled “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
Section titled “AjaxHelper”AjaxHelper 在 HTML 標籤上添加 data-* 屬性,供 unobtrusive 使用,透過 jquery.unobtrusive-ajax.js 讓 HTML 標籤擁有 AJAX 的能力