前情提要:
上一節我們大致把MVC的主要結構和需要用到的知識羅列了一些。本節我們將對利用Razor語法來實現一個基本的表單靜態顯示,以初步瞭解MVC程序是如何運行的。
MVC的構建:
我們在寫之前要了解我們具體實現的業務邏輯是一個表單提交,今天我們只講前臺顯示不涉及後臺數據處理。那就很簡單了,前臺顯示首先我們需要用到JQuery庫,BootStrap庫,以及頁面上所引用的Model數據模型,頁面初始化Action。我們都需要有一個大致的輪廓。
Model數據模型:
如圖所示,這是我們的Model的數據模型關係圖。共有五個實體,每個實體有不同的字段。
Users(用戶):【UserId(主鍵),UserName,UserPassword,UserDescription】
Roles(角色):【RoleId(主鍵),RoleId,RoleName,RoleNote】
Permission(權限):【PermissionId(主鍵),PermissionName,PermissionNote】
User_Role(用戶角色關聯):主要存儲用戶和角色的關聯用戶和角色是1對多關係。【UserRoleId,(Users)Users,(Roles)Roles】
Role_Permission(角色權限關聯):主要存儲角色和權限的關聯角色和權限是1對多關係。
【RolePermissionId,RolePermissionNote, (Roles)Roles,(Permission)Permission】
五個實體將會完成賬戶權限模塊的數據支持,這裏封裝數據就是爲了易用,把相同屬性的某一類集合放在同一實體防止數據被惡意或無意破壞。
在數據模型這一塊還有一個重要的技術Entity Freamwork。三種驅動模式(CodeFirst,Database First,Model First)Code First就是以代碼的方式建立數據模型關係,映射數據庫自動創建DB。Database First已知數據庫根據已知編寫Model代碼。Model First需要熟練掌握建模語言,以關係圖來描繪數據關係,並且自動映射數據庫和自創建Model對象。有興趣可以瞭解一下,我是採用最笨的方法先在文檔內設計數據模型,在數據庫中搭建模型,在代碼中創建相應的對象來進行開發。
View搭建:
上文構建了數據模型,在此我們回顧一下超文本標記語言就是HTML,HTML是一種文本標記語言有各種各樣的標籤,也是網頁形成的基本形態,與CSS(樣式表單)和Javascript(讀寫HTML元素)組成了網頁的基本概念。也就是語義,表現和行爲。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title></title>
</head>
<body>
</body>
</html>
如圖所示這就是最基本的HTML方式。但是我們今天所要展示的是另外一種語法Razor,他可以直接綁定Model或者利用lamda表達式model => model.UserPassword給指定元素綁定Model。這是Razor語法最特別的地方。當然我們不想用Razor也可以他倆是可以互相嵌套的,而且即使採用純HTML編寫也不用擔心數據綁定,現在涌現了一大堆第三方庫,例如Knockout.js,Angular.js,以及可以寫輕量級的Node.js編寫簡單的網站就不需要重量級語言(C#,JAVA)看場子。JS有欲稱霸宇宙之勢還不快去膜拜。
@model BBS.Show.Models.Users
@*
綁定Model實體類
*@
@{
ViewBag.Title = "test";
}
<!DOCTYPE html>
<html>
<head>
<title>登錄驗證</title>
</head>
<body>
<!--Html.BeginForm()等同於在html代碼裏寫<form>.....</form>是一樣的-->
@using (Html.BeginForm("Submit", "GUIHead"))
{
<div>
ID:
</div>
<div>
<!--創建用戶名文本框,等同於<input type="text" />-->
@Html.TextBoxFor(model => model.UserId)
</div>
<div>
Name:
</div>
<div>
<!--創建用戶名文本框,等同於<input type="text" />-->
@Html.TextBoxFor(model => model.UserName)
</div>
<div>
Password:
</div>
<div>
<!--創建用戶密碼文本框,等同於<input type="password" />-->
@Html.PasswordFor(model => model.UserPassword)
</div>
<div>
Role:
</div>
<div>
<!--創建用戶名文本框,等同於<input type="password" />-->
@Html.DropDownListFor(model => model.Roles, ViewBag.Age as List<SelectListItem>)
@*Lambda表達式綁定model指向實體類屬性Roles ViewBag和ViewData是MVC特有的前後臺傳值的方式之一。
var testList = new List<SelectListItem>();
ViewData["Age"] = testList;
Controller定義了一個ViewData並賦予List對象(testList)
*@
</div>
<div>
@{
Int32 id = 100;
Int32 ID = 9527;
string Name = "大寫NAME";
string name = "小寫區分";
}
</div>
<div
>@id</div>
<div
>@ID</div>
<div
>@Name</div>
<div
>@name</div>
<div>Hi@name</div>
<div>
@{
//註釋單行
}
@*
在"{代碼塊}"中的變量聲明要以";"分號結束,使用變量時無需求加";"分號。
"@"符號前不能有任何Html字符,否則變量將以字符串的形式原樣輸出。
與C#在類中寫變量的時候一樣,Razor中也是區分大小寫的。*@
</div>
<div>字符串拼接:aa @name bb </div>
<div>字符串拼接:Begin@{ @Name}</div>
@*
在這部分@{}代碼塊類似於MVVM(Model View ViewModel)中的ViewModel,有興趣可參考Knockout.jsAPI文檔
*@
}
</body>
</html>
View優化:
主要從結構上優化,本節主要對前端知識做一個介紹,告訴大家如何找到解決問題的方法。
HTML&CSHTML
@model BBS.Show.Models.Users
@{
ViewBag.Title = "Index";
Layout = null;
}
<!DOCTYPE HTML>
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>Login</title>
@Styles.Render("~/Common/Css")
@Styles.Render("~/Login/Css")
<body>
@using (Html.BeginForm("Submit", "Login"))
{
<div id="login" >
<div class="form-group">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
@Html.TextBoxFor(model => model.UserName)
</div>
<div class="form-group">
<span class="glyphicon glyphicon-th" aria-hidden="true"></span>
@Html.PasswordFor(model => model.UserPassword)
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Remember me !
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
}
@Scripts.Render("~/Common/JS")
@Scripts.Render("~/Login/JS")
</body>
</html>
View中的代碼就是這些,兩個Text,一個CheckBox,帶一個Button。
我們首先在頭上加上Model,我們既然利用MVC那麼頁面綁定Model這是必然的。@model BBS.Show.Models.Users。Title就不用介紹了就是頁面名稱和Title標籤一樣。Layout母版頁,寫過ASP.NET 的都知道Master Page。在這裏Layout和Master Page是一樣的。
在前一小節我說過View部分可以混合搭配來。head body還是一樣。唯一不同的是在這裏:
@Styles.Render("~/Common/Css")@Styles.Render("~/Login/Css")
和
@Scripts.Render("~/Common/JS")@Scripts.Render("~/Login/JS")
採用Bundle方式。我們爲了便於引用把公共的和私有的分開。
@using (Html.BeginForm("Submit", "Login"))
這句代碼很重要,我們是登錄驗證肯定屬於表單驗證這類。這句話的意思是我們把表單提交到Login Action下的Submit Function裏。並且
我們在Submit函數裏定義一個Users對象來接收表單內容。
public ActionResult Submit(Users uses)
{
業務處理並返回
return RedirectToAction("Index");
}
最後一個內容也是今天表單設計的重頭戲,我們千篇一律的看慣了方塊設計,我們今天一起來感受一下高大上的UI設計,這部分是我的個人愛
好,也只是會用,具體的邏輯還是去查API文檔比較妥,可能講的只是皮毛。
<form>
<div id="login">
<div class="form-group">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
@Html.TextBoxFor(model => model.UserName)
</div>
<div class="form-group">
<span class="glyphicon glyphicon-th" aria-hidden="true"></span>
@Html.PasswordFor(model => model.UserPassword)
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Remember me !
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
其實我們標籤結構就是如此如此。
前端庫:
jquery.js API:http://jquery.cuishifeng.cn/
bootstrap.js API:http://www.bootcss.com/
jquery.ripples Demo:http://www.oschina.net/p/jquery-ripples
JQuery就不用再多說它是網頁編寫的三大巨頭之一,HTML是內容 CSS是表現 JS是行爲。JS裏所有的內容都是圍繞HTML展開的DOM元素各種選
擇器,JQuery在JS基礎上封裝了一套API,更易用,簡單。
BootStrap是一個UI框架。提供了很好看的庫我們只需要在頁面加上Class屬性自然而然就變得毫無違和感。大氣上檔次首選。
jquery.ripples是一個小插件,提供了一個動態背景效果。
關鍵點在這裏:
@Html.TextBoxFor(model => model.UserName)
@Html.PasswordFor(model => model.UserPassword)
這兩位的DOM元素如何獲取,成了一個問題。
1.通過標籤(本頁面是一個元素,但是別的頁面就不行了啊!)
2.通過ID。在學習前端的時候,肯定有人提過儘量多使用ID獲取。那麼ID是啥呢就是model的屬性名 UserName和UserPassword。
還有別的方式來獲取DOM,通過屬性,通過各種各樣我只是舉例而已。
我們知道BootStrap是通過Class屬性給與UI顯示。這兩位沒有class屬性怎麼辦。那我們就加唄!怎麼加用什麼加使用原生的JS還是JQ還是
怎樣。當我們知道JQ更方便,所以選擇JQ。(我是想表達找到問題的根本原因,並找到解決問題的捷徑,而這個問題只是個示例。主要是這個
問題太傻比了)。查看API有一個attr()的方法就是加屬性的。
引入JS。也可以在頁面上直接寫。我決定用第一種。我分別引入兩個JS:Login_Init.js和AddStyleParameter.js。
AddStyleParameter.js裏:
function addClassinDiv() {
var nameClass = $("#UserName");
var pwdClass = $("#UserPassword");
nameClass.attr("class", "form-control");
nameClass.attr("placeholder", "Name");
pwdClass.attr("class", "form-control");
pwdClass.attr("placeholder", "PassWord");
}
獲取DOM元素賦予其class和placeholdder屬性。這只是業務邏輯。
$(function () {
addClassinDiv();
});
Init.JS 纔是真正去調用的。我把JS放到最後加載,CSS放在最前。這樣有利於頁面優化。我們看一下效果:
扁平化風格是不是很騷氣。BootStrap上有很多實例,多練練手,比啥都強光看不行的。
第二個庫jquery.ripples這個具體是如何實現的我沒研究過,使用起來很簡單。首先你得有JQuery庫和這個庫引入頁面。
function LoginPageRipples() {
$('form').ripples({
resolution: 512,
dropRadius: 20, //px
perturbance: 0.04,
});
我們在AddStyleParameter.js再定義一個Function寫完業務邏輯,同樣壓在Init裏調用即可。
參數解答:
resolution參數是分辨率代表水紋效果的細緻程度,越大越細緻。
dropRadius參數是範圍水珠掉落水面時的接觸範圍。
perturbance參數是擾動係數可以理解爲對應於水珠墜落時的力度。
效果如圖所示:當鼠標滑過頁面泛起漣漪是不是很屌。
圖片效果是靜態的,大家可以試試自己練練手效果很炫酷。
這逼裝的可以,給滿分。