前情提要:
上一节我们大致把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参数是扰动系数可以理解为对应于水珠坠落时的力度。
效果如图所示:当鼠标滑过页面泛起涟漪是不是很屌。
图片效果是静态的,大家可以试试自己练练手效果很炫酷。
这逼装的可以,给满分。