码迷,mamicode.com
首页 > Web开发 > 详细

ASP.NET MVC4+BootStrap 实战(七)

时间:2015-01-19 00:26:11      阅读:954      评论:0      收藏:0      [点我收藏+]

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

ASP.NET MVC4+BootStrap 实战(七)

标签:angular post   html5验证   angular directive   angular 指令   

原文地址:http://leelei.blog.51cto.com/856755/1605348

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!