1.6 檢視與 Razor

ASP.NET MVC 實務精要|第一章 快速入門

檢視頁負責網頁的組成,如前一個小節示範的商品展示頁,除了固定的HTML標籤,同時包含以 @ 字元開頭的Razor語法敘述構成的動態內容。Razor是檢視引擎,負責動態建構檢視頁的內容與外觀,透過其專屬的語法,整合程式碼與資料,並在需要的時候結合HTML標籤,輸出至瀏覽器以呈現網頁內容。回到 Products.cshtml 檢視檔案,來看看其中的第一行:

@model IEnumerable<FirstMVC.Models.Item>

這是一行Razor語法,因此以@字元開始,而 @model宣告了 model 物件型態,這個型態必須對應後續控制器傳送過來的資料型態,以這個檢視檔案所接收的控制器HelloController.cs 動作方法Products(),其中內容如下:

public ActionResult Products()
{
KTBookStore db = new KTBookStore();
var rows = db.Items ;
return View(rows);
}

請特別注意最後一行,參數 rows 為一  IEnumerable<FirstMVC.Models.Item> 相容型態的物件,它被傳送至檢視中,因此在檢視中透過model 物件即可將其接收下來。
完成model物件宣告之後,接下來於檢視中,就可以進一步透過 Razor 的 Model 關鍵字存取控制器傳送過來的資料物件,也就是上述的 rows ,而在這個範例中,rows包含了數筆書籍資料,因此透過 foreach 語法逐一將其取出,並且針對每一筆資料存取其欄位內容,最後整合<table>標籤以表格型式輸出。

在Products.cshtml 檢視檔案中,除了以 @ 為字首,Razor 語法包含了兩種不同的格式,如果要即時取得某個特定的值,例如為了逐筆呈現所有取得的資料欄位內容,於每一個標籤中撰寫了以下的語法:

@Html.DisplayFor(item => item.Name)

這一行Razor 語法會取得此筆 item 資料的 Name 欄位內容,並結合至
標籤中,這是獨立的程式片段。如果某段程式碼並非要取得回傳值而是進行特定的邏輯運算,則需將其封裝於 @{…} 構成的區段中,其中的程式碼必須是合法的C# 程式碼,例如檢視檔案中的設值程式碼:

@{
    ViewBag.Title = "Products";
}

其中執行的設值運算將字串 Products 設定給 ViewBag.Title,而且最後以 ; 結束,形成一段合法的C#程式碼。
如下的foreach巡覽操作亦是一種程式區塊:

@foreach (var item in Model)
{
    
}

其中大括弧區塊的內容會持續輸出,對於製作表格或是清單類型的內容相當有用。
最後,你必須理解的是,這些大括弧構成的區塊執行特定程式邏輯運算,相較於程式片段的內容,並不會有任何回傳值呈現在網頁上。

HTML Helper

在 foreach{} 程式區塊中,除了程式碼,還可以進一步嵌入所需的HTML標籤,例如這個範例中的 <tr> 與 <td> 標籤,而為了方便整合資料與網頁標籤,甚至能夠利用HTML Helper 動態建立標籤,HTML Helper 是 MVC 提供的 HtmlHelper 類別 ,用來協助開發人員產生各種HTML標籤內容。現在以 Products.cshtml 其中的取得item 資料的Razor程式碼為例:

@Html.DisplayFor(modelItem => item.ItemId)

緊接著 @ 後方的 Html 會取得一個 HtmlHelper 類別物件,它提供了大量的方法支援檢視的建立,DisplayFor() 即為其中一個方法成員,它會回傳小括弧裏運算式的結果文字內容,因此如果開啟這個檢視所產生的網頁原始碼內容,你會看到每筆資料欄位被逐一取出,結合<td>以表格型式呈現,部份內容如下:

<table class="table">
    <tr>
        <th> <span>編號</span></th>
        <th><span>品項名稱</span></th>
        <th><span>價格</span></th>
        <th><span>說明</span></th>
        <th></th>
    </tr>
    <tr>
        <td>1001</td>
        <td>LINQ 精要 </td>
        <td>550</td>
        <td>LINQ 入門語法到各種擴充功能討論</td>
    </tr>

</table>

這裏僅是單純的取出運算式的內容文字將其呈現出來,後續我們會看到更多的設計討論。

ViewBag資料字典

前一個小節討論Razor語法時,我們看到了引用 ViewBag 屬性的程式片段如下:

ViewBag.Title = "Products";

ViewBag 是一種資料字典屬性,可以同時在控制器與檢視中進行存取,因為這個特性,當我們需要在檢視與控制器中進行資料溝通時,即可透過ViewBag來完成。現在於HelloController控制器中建立一個動作方法 CompanyInfo() 並且配置以下的內容:

public ActionResult CompanyInfo()
{
ViewBag.CompanyName = "康廷數位" ;
 ViewBag.CDescription1 = "HTML5 ASP.NET MVC 教育訓練與技術圖書出版";
ViewBag.CDescription2 = "網站平台開發設計";
return View();
}

其中建立了三個自訂的清單值:CompanyName、CDescription1與CDescription2,儲存網站名稱與相關資訊,最後回傳檢視檔案。針對此動作方法新增檢視CompanyInfo.cshtml,並且於其中撰寫如下的內容:

@{
    ViewBag.Title = "CompanyInfo";
}
<h1>@ViewBag.CompanyName</h1>
<div>
    <P>@ViewBag.CDescription1</P>
    <p>@ViewBag.CDescription2</p>
</div>


其中包含三行以@開始的Razor程式片段,分別引用動作方法中設定的ViewBag屬性值,並且將其呈現於畫面中,檢視結果如下:


當然你也可以在檢視檔案中設定ViewBag,就如同每個新的檢視建立時預設會有以下的Razor 程式碼:

@{
    ViewBag.Title = "CompanyInfo";
}

在預設的情形下,ViewBag.Title用來表示網頁的標題,這一行將其設定為檢視的名稱,你可以自行修改,而完成ViewBag設定,其它檢視亦能取得此屬性值,關於ViewBag.Title的細節,後續討論預設樣板時會有進一步的說明。

ViewBag 進一步包裝 ViewData 以簡化資料的存取設定,更正式的,你可以利用 ViewData 完成相同的資料存取操作,上述的範例修改如下:

ViewData["CompanyName"] = "康廷數位";
ViewData["CDescription1"] = " HTML5 ASP.NET MVC 教育訓練與技術圖書出版";
ViewData["CDescription2"] = "ViewData-網站平台開發設計";

在檢視中,可以透過ViewData 進一步作存取如下:

<h1>@ViewData["CompanyName"]</h1>
<div>
    <p>@ViewData["CDescription1"]</p>
    <p>@ViewData["CDescription2"]</p>
</div>

於瀏覽器檢視會得到相同的結果,讀者可以進一步自行測試,ViewData與ViewBag設定的資料可以相互存取,因此你可以根據自已的需求,任意使用ViewData或是ViewBag進行操作。


沒有留言: