前情提要:
上一節我們大緻把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 >
<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>[email protected]</div>
<div>
@{
//注釋單行
}
@*
在"{代碼塊}"中的變量聲明要以";"分号結束,使用變量時無需求加";"分号。
"@"符号前不能有任何Html字元,否則變量将以字元串的形式原樣輸出。
與C#在類中寫變量的時候一樣,Razor中也是區分大小寫的。*@
</div>
<div>字元串拼接:aa @name bb </div>
<div>字元串拼接:[email protected]{ @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參數是擾動系數可以了解為對應于水珠墜落時的力度。
效果如圖所示:當滑鼠滑過頁面泛起漣漪是不是很屌。
圖檔效果是靜态的,大家可以試試自己練練手效果很炫酷。
這逼裝的可以,給滿分。