1.8 關於佈局

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

ASP.NET MVC最終產生的網頁,可能是單純的檢視檔案,或是整合其它特定內容的複合式結果,在預設的情形下,一個新建立的MVC專案以 BootStrap 為預設樣板,並內建了共用樣板,讓後續建立的檢視檔案套用以建立風格一致的網頁內容。

MVC專案預設將所有的View檔案配置於專案根目錄下的Views資料夾,並根據關聯的控制器動作方法進行組織命名。



以新建立的專案為例,預設檔案架構中的 Views 資料夾儲存所有的View檔案,底下配置了三個子資料夾,Account 包含驗證與授權機制支援的檢視檔案,對應至 Controllers 資料夾中的 AccountControlller.cs控制器,資料夾 Home 則對應至 HomeControlller.cs 控制器。

展開其中的Views/Home資料夾,會看到三個檔案-About.cshtml、Contact.cshtml與Index.cshtml,與開啟的控制器HomeControlller.cs內容比對如下:



如你所見,控制器中的每個一動作方法,剛好對應至同名的檢視檔案。考慮以下的網址列字串:

 http://localhost:49924/Home/Index

根據上述的對應規則,當這列網址字串被傳送至伺服器,MVC會從Controllers資料夾中找到 HomeControllers.cs (Home) 這個檔案中的Index動作方法,並執行其中的程式碼 return View() ,從Views 資料夾的 Home 子資料夾中,找出 Index.cshtml 檔案編繹其內容最後傳送至瀏覽器,其它類推。
Index.cshtml 檔案為所要呈現的主要網頁內容,包含了HTML標籤與Razor語法構成的邏輯程式碼,它合併預先配置的共用版面內容,組織所要呈現的網頁內容輸出至瀏覽器。

共用檢視樣版 _Layout.cshtml

第三個資料夾 Views/Shared 資料夾為共用檢視樣版檔案 _Layout.cshtml,協助開發人員建構風格一致的網頁外觀,這個檔案包含了一般網頁需要的共用內容,開啟_Layout.cshtml檔案,來看看它的內容:



這是共用的網頁內容,如你所見,它是標準的網頁架構,body標籤開始緊接著 div 標籤是所要網頁所要呈現的共同標題與功能選單,緊接著第二組div標籤裏面 @RenderBody()套用此版面的檢視檔案內容將會被嵌入這個位置,而footer標籤則呈現共同頁尾內容,例如版權宣告等。有了共用的樣板_Layout.cshtml,接下來其它的檢視就可以直接套用此樣板建立共用的內容。

在專案總管裏面的 \Views 資料夾節點下,有一個 _ViewStart.cshtml 檔案,將其開啟可以看到以下的內容:

@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

如同其名稱(ViewStart)所暗示的,它會在每一個檢視檔案開啟之前執行,如果有套用樣板,則找到Layout 指定的 _Layout.cshtml 樣板檔案,將檢視檔案的內容嵌入其 @RenderBody() 的位置區域,最後產生所需的HTML網頁。現在開啟專案預設啟始頁 /Views/Home/Index.cshtml,於瀏覽器檢視內容如下:



不使用版面配置頁

版面配置頁的設計相當彈性,你可以選擇不使用版面配置頁,現在嘗試於 Index.cs 建立一個 NoLayout 動作方法,然後建立其檢視頁,於「加入檢視」對話方塊中,取消「使用版面配置頁」,如此一來新的檢視頁就會成為獨立的網頁,而不會套用版面配置頁。



現在切換至新建立的檢視頁如下:



一開始的 Layout=null 設定,表示不套用版面配置頁,接下來便是一個標準網頁的內容。

@RenderSection

在 _Layout.cshtml檔案內容下方,body 結束標籤之前有一行設定如下 :

@RenderSection("scripts", required: false)

@RenderSection表示於此處呈現套用此樣版的檢視內容中標示為 scripts 的 section 內容,有了這個設定,就可以利用以下的語法,在套用_Layout.cshtml的檢視裏將指定內容嵌入主網頁的這個位置:

@section scripts{
     // 嵌入_Layout.cshtml樣版中 @RenderSection 中,標示如下
     // @RenderSection("scripts", required: false) 的位置

其中的 scripts 為自行任意指定的區段識別名稱,命名為 scripts 通常表示要插入的 JavaScript ,同樣的,你也可以透過 RenderSection 配置另外一個區段,以方便樣式的嵌入。
為了方便理解,這裏實作一個範例作說明,於控制器HomeController.cs裏新增一個動作方法如下:

public ActionResult Section_Demo(){
return View();
}

建立其對應的檢視,為了套用樣版,在「加入檢視」對話方塊中,請注意下方的「使用版面配置面」預設為勾選,按一下「加入」按鈕建立一個新的檢視:



現在於路徑 / Views/ Home/ Section_Demo.cshtml 找到新加入的檢視,將其開啟並且新增以下的內容:

@{
    ViewBag.Title = "Section_Demo";
}
@section styles{
    <style>
        #message{
            font-size:36px;
            color:#f00;
        }
    </style>
}
@section scripts{
    <script>
        document.getElementById('message').innerHTML = 'Hello Section !';
    </script>
}
<h2>Section_Demo</h2>

這個網頁在最後一行配置了 id="message" 的 div 元素,並且分別於 styles 區塊定義針對div 內容所要套用的 CSS 樣式,並於 scripts 區塊中定義所需的 JavaScript ,於 div 中建立測試用的訊息文字。現在切換至_Layout.html 將其開啟,於其中head結束標籤之前,加入另外一個section 定義如下:

@RenderSection("styles", required: false)

如此一來前述檢視中 @section styles大括弧內的樣式設定,將會嵌入這個位置。現在於瀏覽器檢視 http://localhost:xxx/Home/Section_Demo 得到以下的內容:


這個網頁透過JavaScript與CSS樣式建立此網頁內容,於瀏覽器檢視原始碼,結果如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Section_Demo - 我的 ASP.NET 應用程式</title>
    <link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
    <script src="/Scripts/modernizr-2.6.2.js"></script>   
    <style>
        #message{
            font-size:36px;
            color:#f00;
        }
    </style>
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                …
                …
            </div>
        </div>
    </div>
    <div class="container body-content">
<h2>Section_Demo</h2>
<div id="message"></div>
        <hr />
        <footer>
            <p>&copy; 2014 - 我的 ASP.NET 應用程式</p>
        </footer>
    </div>
    <script src="/Scripts/jquery-1.10.2.js"></script>
    <script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>   
    <script>
        document.getElementById('message').innerHTML = 'Hello Section !';
    </script>

其中以網底標示的部份,為檢視Section_Demo.cshtml嵌入版面檢視的內容,第一段style 元素的內容來至Section_Demo.cshtml中 @section styles{…} 這段配置的大括弧內容,對應至版面中@RenderSection為styles 的位置,第二段則是檢視的主體內容,配置於@RenderBody() 標示的位置,最後一段script 元素內容則是Section_Demo.cshtml中 @section scripts{…} 大括弧中的內容,對應至版面中@RenderSection為scripts 的位置。

最後,展開版面檢視 _Layout.cshtml與套用此版面的檢視Section_Demo.cshtml如下圖,其中Section_Demo.cshtml檢視的內容嵌入了RenderBody()區域,而特定區塊的內容再根據名稱分配於對應的RenderSection。



Partial Views

在_Layout.cshtml 這個版面配置頁中,無論是專案預設首頁index.cshtml或是上述建立的Section_Demo.cshtml,右上角均配置了一個共用的登入/註冊功能區塊,如下圖:





切換至版面配置頁_Layout.cshtml的內容,可以發現登入區塊並非如左邊的導覽功能直接配置,而是以 Partial View 區塊嵌入。



Html.Partial() 接受一個參數,表示要嵌入此位置的部份檢視內容,這裏指定的參數為_LoginPartial,如此在同一個目錄下的_LoginPartial.cshtml 會被嵌入其中成為版面配置頁的一部份,開啟這個檢視檔案,其內容如下:



這個檔案支援驗證授權機制,其中的if判斷式根據目前的驗證狀態,決定呈現的內容,如果完成驗證提供歡迎訊息與「登出」功能,如果不是的話,則呈現「註冊」與「登入」功能,也就是目前我們看到的功能。
如果有一組特定標籤內容由其它的檢視所共用,可以先將其封裝成為一個獨立的檢視檔案,接下來只要透過Html.Partial()將其嵌入目前的檢視頁即可,由於只是部份的網頁內容,因此稱為Partial View(部份檢視)。 


沒有留言: