标签:angular post html5验证 angular directive angular 指令
连续三年年会中奖,第一年二等奖,价值2600元的魔音耳机,到现在才用了10几次。第二年中了个价值260元的飞利浦烧水壶,到现在还没用。今年中了个飞利浦挂烫机,也没查是多少钱,反正觉得奖项一年不如一年。在此我就给大家上一张年会热图。
男人的肚皮舞,嗨爆全场。好了,废话不多说,我们进入正题吧。
今天我们要说的就是主页面以及用户注册界面,功能做的都比较简单,我们先看一下Index界面。
<div id="div_navigation" style="margin-top:10px;" ng-app="indexModule" ng-controller="indexController">
<div class="row">
<div class="col-md-3">
<div class="panel-group" id="accordion">
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseOne">
<b>用户管理</b>
</a>
</h4>
</div>
<div id="collapseOne" class="panel-collapse collapse in">
<div class="panel-body">
<ul class="navigation-ul">
<li>
<img src="~/Images/Base/usermng.jpg" />
<a href="#" onclick="redirectToPage(‘UserCreateView‘)">用户注册</a>
</li>
<li>
<img src="~/Images/Base/useradd.png" />
<a href="#" onclick="redirectToPage(‘UserManageView‘)">用户管理</a>
</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseTwo">
<b>新闻管理</b>
</a>
</h4>
</div>
<div id="collapseTwo" class="panel-collapse collapse">
<div class="panel-body">
<ul class="navigation-ul">
<li>
<img src="~/Images/Base/newsadd.png" />新增新闻
</li>
<li>
<img src="~/Images/Base/newsquery.png" />新闻查询
</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseThree">
<b>图片管理</b>
</a>
</h4>
</div>
<div id="collapseThree" class="panel-collapse collapse">
<div class="panel-body">
<ul class="navigation-ul">
<li>
<img src="~/Images/Base/photomng.jpg" />图片查看
</li>
<li>
<img src="~/Images/Base/photorar.jpg" />图片压缩
</li>
</ul>
</div>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapseSys">
<b>系统管理</b>
</a>
</h4>
</div>
<div id="collapseSys" class="panel-collapse collapse">
<div class="panel-body">
<ul class="navigation-ul">
<li>
<img src="~/Images/Base/syscodemng.jpg" />系统参数管理
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div id="div_content" class="col-md-9" style="padding-left:1px;">
@Html.Partial("~/Views/UserManage/UserCreate.cshtml")
</div>
</div>
</div>
<script type="text/javascript">
function redirectToPage(action) {
var baseURL = ‘/Home/‘;
$.get(baseURL + action).success(function (data, status) {
$("#div_content").html(data);
});
}
//var indexModule = angular.module(‘indexModule‘, []);
//indexModule.controller("indexController", function ($scope, $http) {
// $scope.redirectToPage = function (action) {
// var baseURL = ‘/Home/‘;
// $http.get(baseURL + action).success(function (data) {
// angular.element(‘#div_content‘).html(data);
// });
// };
//});
//angular.bootstrap(angular.element(‘#div_navigation‘), [‘indexModule‘]);
</script>这个其实就是Index界面的全部代码,Index界面应用了布局模版。布局模版很简单,在这里代码就不贴出来了,主要是引用一些Js,css。OK,我们首先看一下页面是如何导航的。
<li> <img src="~/Images/Base/usermng.jpg" /> <a href="#" onclick="redirectToPage(‘UserCreateView‘)">用户注册</a> </li> <li> <img src="~/Images/Base/useradd.png" /> <a href="#" onclick="redirectToPage(‘UserManageView‘)">用户管理</a> </li>
从这两段代码就可以看出来,在超链接onclick的时候,我们调用js方法redirectToPage。在这个方法中,我们调用action获取对应的页面显示到div_content中。上节我说过了,如果使用ng-click调用$scope中的方法,是会有问题的,因为module只能注册一次,如果每次点击导航链接你的页面都是整页刷新,则没有问题。只要你在每个页面上注册module就行了。
angular.bootstrap(angular.element(‘#div_navigation‘), [‘indexModule‘]);
但是局部刷新,则不行,所以angular js是不支持多个页面以tab页形式加载到主页面的,是无法正常工作的。所以上面注释的代码就是没办法使用的,因为我们的界面是在主界面不停的更换如下div中的内容。
<div id="div_content" class="col-md-9" style="padding-left:1px;">
@Html.Partial("~/Views/UserManage/UserCreate.cshtml")
</div>ok,我们看一下action。
public PartialViewResult UserCreateView()
{
return PartialView("~/Views/UserManage/UserCreate.cshtml");
}
public PartialViewResult UserManageView()
{
return PartialView("~/Views/UserManage/UserManage.cshtml");
}就是两个返回PartialView的action。ok,到此我们的主页导航就完了。
接着我们看一下用户注册界面。
很简单的一个页面,那么首先先看一下页面。
@{
Layout = null;
}
<form id="div_userCreate" ng-app="userCreateModule" autocomplete="off" ng-submit="saveUser()" class="form-horizontal" role="form" ng-controller="createUserController">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">
<b>用户注册</b>
</h3>
</div>
<div class="div-panel-content">
<div class="form-group">
<label class="col-sm-2 control-label">用户名:</label>
<div class="col-sm-10 col-sm-5-pad">
<input name="userNo"
type="text"
maxlength="15"
placeholder="请输入登录用户名"
ng-model="userInfo.userNo"
class="form-control element-form-width"
data-toggle="tooltip"
data-placement="right"
pattern="^[a-zA-Z]\w{5,15}$"
title="用户名必须以字母开头,并且只能是字母和数字及下划线的组合(6-15位)" required>
</div>
</div>
<div class="form-group">
<label for="inputPassword" class="col-sm-2 control-label">
密码:
</label>
<div class="col-sm-10 col-sm-5-pad">
<input name="passWord" ng-model="userInfo.passWord" class="form-control element-form-width" type="password" maxlength="15"
placeholder="请输入密码" data-toggle="tooltip" pattern="^\w+$"
data-placement="right" title="密码由字母和数字组成,不能超过15位" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">姓名:</label>
<div class="col-sm-10 col-sm-5-pad">
<input name="userName"
type="text"
maxlength="10"
ng-model="userInfo.userName"
class="form-control element-form-width"
data-toggle="tooltip"
data-placement="right"
title="姓名不能超过10个汉字" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
性别:
</label>
<div class="col-sm-10 col-sm-5-pad">
<div class="radio-inline">
<label>
<input ng-model="userInfo.sex" ng-checked="true" name="radioSex" type="radio" value="1">男
</label>
</div>
<div class="radio-inline">
<label>
<input name="radioSex" type="radio" value="0">女
</label>
</div>
</div>
</div>
<div class="form-group">
<label for="disabledSelect" class="col-sm-2 control-label">
出生日期
</label>
<div class="col-sm-10 col-sm-5-pad">
<input id="txtBirthDay" ng-model="userInfo.birthDay" type="date" class="form-control element-form-width" required />
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
Emai:
</label>
<div class="col-sm-10 col-sm-5-pad">
<input type="email" maxlength="30" ng-model="userInfo.email" class="form-control element-form-width" id="txtEmail" data-toggle="tooltip"
data-placement="right" title="请填写正确的邮箱地址,用于找回密码等" required>
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label">
电话:
</label>
<div class="col-sm-10 col-sm-5-pad">
<input type="tel" maxlength="15" ng-model="userInfo.telPhone" class="form-control element-form-width" id="txtTelNo" data-toggle="tooltip"
data-placement="right" pattern="^\d{11}$" title="只能输入11位手机号码" required>
</div>
</div>
<div class="form-group">
<div class="col-sm-5 col-sm-offset-2" style="padding-left:2px">
<button id="btnSave" type="submit" class="btn btn-primary btn-form-width">保存</button>
<button type="reset" class="btn btn-primary btn-form-width">取消</button>
</div>
</div>
<loading></loading>
</div>
</div>
<script>
var nowDateTime = getDateNow();
var appModule = angular.module(‘userCreateModule‘, []);
appModule.directive(‘loading‘, function () {
return {
restrict: ‘E‘,
replace: true,
template: ‘<div style="margin-left:10px"><img src="./../Images/Base/loading.gif" style="height:35px;width:35px"/>‘ +
‘<label style="margin-left:10px;color:#CC0033">正在处理,请稍后...</lable>‘ +
‘</div>‘,
link: function (scope, element, attr) {
scope.$watch(‘isLoading‘, function (val) {
if (val) {
$(element).show();
}
else
$(element).hide();
});
}
}
});
appModule.controller("createUserController", function ($scope, $http) {
$scope.isLoading = false;
$scope.userInfo = {
userNo: "",
passWord: "",
userName: "",
sex: "1",
birthDay: nowDateTime,
email: "",
telPhone: ""
};
//convertParam($http);
$scope.saveUser = function () {
$scope.isLoading = true;
var postData = {
requestJson: JSON.stringify({
userInfo: {
userNo: $scope.userInfo.userNo,
passWord: $scope.userInfo.passWord,
userName: $scope.userInfo.userName,
sex: $scope.userInfo.sex,
birthDay: $scope.userInfo.birthDay,
email: $scope.userInfo.email,
telPhone: $scope.userInfo.telPhone
}
})
};
$http({
url: "/UserManage/CreateUser",
method: "POST",
headers: { ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ },
data: $.param(postData)
}).success(function (data, status, headers, config) {
$scope.isLoading = false;
alert(data.msg);
}).error(function (data, status, headers, config) {
alert(status);
$scope.isLoading = false;
});
//$.ajax({
// url: "/UserManage/CreateUser",
// type: "POST",
// dataType: "json",
// data: postData,
// success: function (data) {
// $scope.isLoading = false;
// alert(data.msg);
// }, error: function () {
// $scope.isLoading = false;
// }
//});
}
});
angular.bootstrap(angular.element(‘#div_userCreate‘), [‘userCreateModule‘]);
$("[data-toggle=‘tooltip‘]").tooltip();
</script>
</form>加载到主页面中的每个Partial页面都必须设置Layout=null,不要应用布局模版。该页面必须还是BootStrap布局,ng-app,ng-controller,ng-submit这三个标签我在此就不再多说了。我们先看一下用户名表单。
<input name="userNo"
type="text"
maxlength="15"
placeholder="请输入登录用户名"
ng-model="userInfo.userNo"
class="form-control element-form-width"
data-toggle="tooltip"
data-placement="right"
pattern="^[a-zA-Z]\w{5,15}$"
title="用户名必须以字母开头,并且只能是字母和数字及下划线的组合(6-15位)" required>注意,这里我们设置最大长度为15,绑定的model变量是userInfo.userNo。为什么是这样,因为我们整个表单对象是userInfo。所以在controller中我们首先初始化了userInfo这个Json对象。
$scope.userInfo = {
userNo: "",
passWord: "",
userName: "",
sex: "1",
birthDay: nowDateTime,
email: "",
telPhone: ""
};再看有个属性data-toggle,data-placement,这两个其实是BootStrap提供的用来展示tooltip的属性。看一下效果
看到了吧,其实这里大家发现它把title的内容显示在了这里,并且tooltip是显示在了右边,data-placement这个属性设置是显示在哪边,有right,left,top,bottom四个值,那么这个tooltip仅仅是设置了这两个属性就会鼠标mouseover的时候显示?No,还有一段js。
$("[data-toggle=‘tooltip‘]").tooltip();OK,最后我们看到有个Pattern属性,这个不是BootStrap的,是Html5的。我们在这里设置了用户名必须是以字母开头,6-15位,看一下下面的效果图。
OK,其他的元素我就不说了,我们再看一下Email。
<input type="email" maxlength="30" ng-model="userInfo.email" class="form-control element-form-width" id="txtEmail" data-toggle="tooltip" data-placement="right" title="请填写正确的邮箱地址,用于找回密码等" required>
type=email,这个是html5提供的。在这里我们不需要写任何的正则验证,他自己会验证的。
看到了吧,通不过,我们改成带有@的试试。
最后我们填写完整,提交。
看到了吧,出现了正在处理,请稍后的字样。那么这个正在处理请稍后,是怎么整的呢?其实第一篇我们在讲Login界面的时候,用的Jquery的ajax。beforsend时展示一个div,success的时候隐藏div。但是在这里我们使用到了angular js的指令。
appModule.directive(‘loading‘, function () {
return {
restrict: ‘E‘,
replace: true,
template: ‘<div style="margin-left:10px"><img src="./../Images/Base/loading.gif" style="height:35px;width:35px"/>‘ +
‘<label style="margin-left:10px;color:#CC0033">正在处理,请稍后...</lable>‘ +
‘</div>‘,
link: function (scope, element, attr) {
scope.$watch(‘isLoading‘, function (val) {
if (val) {
$(element).show();
}
else
$(element).hide();
});
}
}
});指令可以应用于元素,属性等。在这里我们将其设置为只能应用于元素(E),我们为其设置了一个template,用来替换页面中的指令标签内容。同时我们提供了一个link函数,用来实现模版是否显示的逻辑。如下是关于restrict和replace的解释
通过上面的这段解释,我们可以设置模版url而非像上面直接在指令中设置模版内容。
好的,再看一下link函数的解释
上面都是官方翻译的文档,没什么可以解释的,毕竟这东西不是我发明的。
在link函数中,我们通过一个isLoading变量来控制指令元素的显示隐藏,OK,说了这么多,这个指令就是html页面中的如下标签
那么我们在controller中是如何调用的呢?
controller中,我们初始化设置这个变量为false,$scope.isLoading = false。
然后在saveUser方法还未发送请求之前,设置这个变量的值为true
$scope.saveUser = function () {
$scope.isLoading = true;此时,正在处理,请稍后就出现了。当然了,在请求结束后设置为false,正在处理,请稍后这个div就消失了。
在这里大家需要注意红框标出来这部分,headers和data。在上节我说过,因为angular post的数据,asp.net mvc action接收不到,原因是发送的数据格式和asp.net mvc所要接收的数据格式不一致。那么为什么jquery的请求action可以收到呢?因为jquery发送的数据格式默认是application/x-www-form-urlencoded,而且对post的数据格式也是进行了转换。
Data to be sent to the server. It is converted to a query string, if not already a string. It‘s appended to the url for GET-requests. See processData option to prevent this automatic processing. Object must be Key/Value pairs. If value is an Array, jQuery serializes multiple values with same key based on the value of the traditional setting (described below).
而angular默认发送的是json格式,所以我们在上节对它post的数据进行了转化。本节我们使用更简单的一种方式让angular $http.post也能正确发送数据到action,设置headers为{ ‘Content-Type‘: ‘application/x-www-form-urlencoded‘ },然后传数据的时候,使用jquery的$.param方法进行转换。这样就不用像上节那样去写一堆东西转换。
OK,说了这么多,我们看一下保存成功了没有。
虽然代码写的是先消失,再弹出alert,但是我们在关闭了alert之后,正在处理请稍后才消失。
OK,最后,再强调一下,一定不要忘了下面这句,这个意思是设置angular的启动入口。
angular.bootstrap(angular.element(‘#div_userCreate‘), [‘userCreateModule‘]);
好了,我们最后看一下后台控制器。
[HttpPost]
public JsonResult CreateUser()
{
string requestJson = Request["requestJson"];
UserAddRequest request = JsonBuilder.BuildUserInfoRequest(requestJson);
request.InUserID = UserID;
int suc = UserInfoBiz.GetInstance().CreateUser(request);
if (suc >= 0)
{
return GetJsonMessage("CM_001");
}
return GetJsonMessage("CM_004");
}接收到数据,然后Json反序列化得到request
public static UserAddRequest BuildUserInfoRequest(string requestJson)
{
if (string.IsNullOrWhiteSpace(requestJson)) return new UserAddRequest();
JObject jObj = (JObject)JsonConvert.DeserializeObject(requestJson);
JToken jToken = jObj["userInfo"];
string userNo = jToken.Value<string>("userNo");
string userName = jToken.Value<string>("userName");
string userPwd = jToken.Value<string>("passWord");
string sex = jToken.Value<string>("sex");
DateTime birthDay = jToken.Value<DateTime>("birthDay");
string email = jToken.Value<string>("email");
string telPhone = jToken.Value<string>("telPhone");
UserAddRequest userInfoRequest = new UserAddRequest();
userInfoRequest.UserID = userNo;
userInfoRequest.UserName = userName;
userInfoRequest.UserPwd = Cryptor.Encrypt(userPwd);
userInfoRequest.UserSex = sex;
userInfoRequest.UserBirthDay = birthDay;
userInfoRequest.UserEmail = email;
userInfoRequest.UserPhone = telPhone;
return userInfoRequest;
}得到request之后,调用Biz=>DAL完成保存,CreateUser脚本如下
<Script Key="CreateUser"> <![CDATA[ IF NOT EXISTS( SELECT TOP 1 1 FROM dbo.InformationUser WITH(NOLOCK) WHERE UserID = @UserID ) BEGIN INSERT INTO dbo.InformationUser ( UserID, UserName, UserPwd, UserSex, UserBirthDay, UserEmail, UserPhone, InDate, InUser ) VALUES ( @UserID, @UserName, @UserPwd, @UserSex, @UserBirthDay, @UserEmail, @UserPhone, GETDATE(), @InUserID ) END ]]> </Script>
OK,到这里代码就全部结束了,最后我们再看看刚才注册的用户能否查出来
OK,没啥问题,在这篇文章里我只做了客户端的验证,在正式开发中后端一定是要有验证的,好了,洗洗睡。
本文出自 “技术创造价值” 博客,请务必保留此出处http://leelei.blog.51cto.com/856755/1605348
标签:angular post html5验证 angular directive angular 指令
原文地址:http://leelei.blog.51cto.com/856755/1605348