夫天地者,万物之逆旅;光阴者,百代之过客。而浮生若梦,为欢几何?
AngularJs中MVC编程模式的应用

前言

目前前端JS框架有很多,而如何进行技术选型不是本文所关心的,因为有需求才是学习的源动力。本文将进一步学习AngularJs,重点是MVC编程模式在AngularJs中的使用。由于Angular的版本有很多,目前已出到Angular9,历史版本依次是:Angular8、Angular7、Angular6、Angular4、Angular2和AngularJs,本文用的是老旧的AngularJs。

项目创建

演示项目是基于ASP.NET MVC的项目创建的,同时结合使用了bootstrap的ui框架,项目目录结构如下:

项目预览

我们先来预览一下项目的运行效果,然后再进行分析具体的实现过程

项目分析

项目如何启动

首先我们创建的是ASP.NET MVC的项目,项目启动后应该是跳转到MVC的默认路由:/Home/Index,但这里直接打开了 /PermissionWeb/page/login的登录页面,这是因为事先在/Home/Index的页面里做了如下跳转的处理:

<body>
    <div>
        <h1 id="error"></h1>        
    </div>
    <script type="text/javascript">
        if (navigator.userAgent.indexOf("MSIE") < 0 || navigator.userAgent.indexOf("MSIE 10.0") > 0) {
            window.location.href = "/PermissionWeb";
        } else {
            document.getElementById("error").innerHTML = "该IE浏览器版本过低,请升级至IE10以上,或使用谷歌浏览器!";
        }
    </script> 
</body>

请求跳转到/PermissionWeb后,会出加载index.html入口文件,而此文件中引入了angularjs库文件以及项目所需的其它js文件,主要是下面两个:

需要说明的是app.js文件,在前面的项目目录结构图中,我们针对不同的页面创建了不同的controller.js和service.js以及module.js、router.js等,在开发过程中,层次清晰,便于维护。而这里的app.js其实就是各个不同js文件的合并,生产环境还会压缩一下,使用app.min.js,主要是为了减少网络请求的次数以及请求的带宽。为了偷懒,这里就只引用了app.js

module:模块

为了能够实现自动跳转到/page/login的登录页面,最核心的是下面这段代码:

(function() {
    'use strict';
    angular
        .module('app.core', [ //app.core模块依赖的其它模块
            'ngRoute',
            'ngAnimate',
            'ngStorage',
            'ngCookies',
            'ui.bootstrap',
            'ui.router',
            'ngResource',
            'ui.utils'
        ]);
})();
(function () {
    'use strict';
    angular
        .module('app.core')
        .run(appRun);
    appRun.$inject = ['$rootScope', '$cookieStore', '$state' '$window'];
    function appRun($rootScope, $cookieStore, $state, $window) {
        // 监听路由成功时触发
        $rootScope.$on('$stateChangeSuccess',
          function () {
              if (!$rootScope.currentUser) {
                  $rootScope.currentUser = $cookieStore.get('currentUser');
                  if (!$rootScope.currentUser) {
                      $state.go('page.login');
                  }
              }
          });
    }
})();

解释说明:

//第一参数表示模块的名称,第二个参数表示此模块依赖的其它模块
var app = angular.module('app',[]);

运行块(run)在注入器创建之后被执行,它是所有AngularJS应用中第一个被执行的方法。运行块是AngularJS中与main方法最接近的概念。到这里我们知道了,在run方法里监听到了路由的变化,且判断用户未登录,即跳转到到登录页面。

$state.go()

上段代码中$state.go('page.login')之所以就能跳转到/page/login页面,是因为如下的路由规则:

(function () {
    'use strict';
    angular.module('app.routes').config(routesConfig);
    routesConfig.$inject = ['$stateProvider', '$locationProvider', '$urlRouterProvider', 'RouteHelpersProvider'];
    function routesConfig($stateProvider, $locationProvider, $urlRouterProvider, helper) {
        //启用HTML5模式
        $locationProvider.html5Mode(false);
        //默认路由
        $urlRouterProvider.otherwise('/page/login');
        
        // 路由规则 
        $stateProvider
            .state('app', {
                url: '/app',
                abstract: true,
                templateUrl: 'app/views/app.html'
            })
            .state('permission', {
                url: '/permission',
                abstract: true,
                templateUrl: 'app/views/app.html'
            })
            .state('permission.menu', {
                url: '/menu',
                title: 'menu',
                templateUrl: 'app/views/permission/menu.html'
            })
            .state('permission.func', {
                url: '/func',
                title: 'func',
                templateUrl: 'app/views/permission/func.html'
            })
            .state('permission.role', {
                url: '/role',
                title: 'role',
                templateUrl: 'app/views/permission/role.html'
            })
            .state('permission.user', {
                url: '/user',
                title: 'user',
                templateUrl: 'app/views/permission/user.html'
            })
            .state('page', {
                url: '/page',
                templateUrl: 'app/pages/page.html'
            })
            .state('page.login', {
                url: '/login',
                title: 'Login',
                templateUrl: 'app/pages/login.html'
            });
    }
})();

controller:控制器

直接上代码:

angular.module('app.pages').controller('LoginFormController', LoginFormController);
//动态实例化controller中注册的服务,如UserService
LoginFormController.$inject = ['$scope', '$state', 'UserService', 'md5'];
function LoginFormController($scope, $state, UserService, md5) {
    $scope.account = {};
    $scope.authMsg = '';
    $scope.login = function () {
        $scope.authMsg = '';
        $scope.account.password = md5.createHash($scope.account.password);
        $scope.isLoading = true;
        UserService.login($scope.account)
            .success(function (response) {
                if (response.Result) {
                    UserService.currentUser = response.Data;
                    //登录成功后默认跳转到用户管理页面
                    $state.go('permission.user');
                } else {
                    $scope.authMsg = response.ErrorMessage;
                }
                $scope.isLoading = false;
            })
            .error(function () {
                $scope.authMsg = '网络连接错误!';
                $scope.isLoading = false;
            });
    };
}
})();

service:服务层

(function () {
    'use strict';
    angular
        .module('app.dataservice')
        .factory('UserService', UserService)
    //UesrService
    UserService.$inject = ['$http'];
    function UserService($http) {
        var service = {
            currentUser: null,
            userMenu: null,
            login: login,
            logOut: logOut,
            getPagedList: getPagedList
        }
        //登录操作:调用MVC项目中的Account控制器中的Login方法
        function login(account) {
            return $http.post('../Account/Login', account);
        }
        function logOut() {
            return $http.get('../Account/LogOut');
        }
        function getPagedList(p) {
            return $http.get('../User/GetUserPagedList', { params: p });
        }
        return service;
    }
})();

到这里,核心代码基本演示完毕。

延伸扩展

Angular中文官网

前端MVC框架之Angular

AngularJs和Angular的对比

作者:一蓑烟雨

本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

0

支持

0

反对

posted @2020-7-23  拜读(377)

评论列表

评论内容:



喜欢请打赏

支付宝 微信

请放心支付