标签: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