车辆管理系统arcgis移植已经基本完成。开始下一件事情,搭建一个视频培训系统。这个系统准备用angularjs+微服务架构的方式搭建,如果有可能再引入CDN。
先用一天时间大致看完了《angularjs权威教程》,由于js的高级编程还算比较扎实,对angularjs基本上已经有了个认识,主要的一个理解要点就是原型继承。
今天就用该技术把框架搭建了一下,然后把登录功能给做了。现在就初步谈谈angularjs的使用感受。
1、angularjs很容易实现模块化的架构,因为它已经具备了这个功能
2、angularjs是一个mvc框架,说一下我对angularjs的mvc的理解
view为前端的视图,可以是任何的标签。
model可以通过ng-model将对象与标签进行绑定。
controller为view与model的粘合剂。
service和指令:个人认为controller应该尽量简洁,业务逻辑可以交给service和指令完成。这里有个很有意思的事情是,service是一个全局的单例。
3、依赖注入,没错,angularjs提供了依赖注入!多么让人激动啊!
4、不同的module,controller之间已经实现了命名空间进行隔离
5、静态化,angular据说支持模板技术,因此方便静态化
6、路由功能,该功能也是非常有意思的,但是这里先不涉及
因此我们搭建的前端架构可以是这样的:
因此有如下的目录组织:
下面上核心代码,为了静态化,不再使用jsp:
1、login.html (登录模块的视图)
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
<link rel="shortcut icon" href="pulse.ico" />
<link rel="stylesheet" href="/ZVideo-MVC/styles/login/login.css"></link>
<style type="text/css">
:root #content > #right > .dose > .dosesingle,
:root #content > #center > .dose > .dosesingle
{ display: none !important; }
input.ng-invalid {
border: 1px solid red;
}
input.ng-valid {
border: 1px solid green;
}
</style>
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body>
<div ng-app=app.login ng-controller="LoginController">
<form id="login" name="loginForm">
<h1>中森视频培训系统登陆</h1>
<fieldset id="inputs">
<input id="loginname" name="loginname" placeholder="请输入用户名(工号)" autofocus="" type="text" ng-model="user.loginname.value" ng-required="true">
<div ng-show="loginForm.loginname.$dirty && loginForm.loginname.$invalid">
<span style="color:red"
ng-show="loginForm.loginname.$error.required">
{{user.loginname.requiredTip}}
</span>
</div>
<input id="password" name="password" placeholder="请输入密码(oa)" type="password" ng-model="user.password.value" ng-required="true">
<div ng-show="loginForm.password.$dirty && loginForm.password.$invalid">
<span style="color:red"
ng-show="loginForm.password.$error.required">
{{user.password.requiredTip}}
</span>
</fieldset>
<fieldset id="actions">
<div ng-model="user" ng-show="user.error.tip">
<span style="color:red"
ng-show="user.error.tip">
{{user.error.tip}}
</span>
</div>
<input id="submit" value="登录" type="submit" ng-disabled="loginForm.$invalid" ng-click="submit()">
<a href="">忘记密码?</a>
</fieldset>
</form>
</div>
<script src="../../jslib/base/loader.js"></script>
<script>
Loader.loadScript("../../jslib/base/angular-1.2.13.min.js",function(){
Loader.loadScript("../../scripts/loginModule/app.js",function(){
Loader.loadScript("../../scripts/loginModule/controllers/loginController.js",function(){
Loader.loadScript("../../scripts/loginModule/services/userService.js",function(){
})})})});
</script>
</body>
</html>
这个文件主要是angular的指令应用,另外Loader是我写的一个js动态加载工具类。因为静态加载对于不同浏览器来说异步加载的数量是有限的。而通过动态加载则不会有限制。
2、app.js (登录模块的主要结构)
(function(angular){
angular.module('app.login',
['LoginController']
);
})(window.angular);
3、loginController.js(登录模块的控制器)
(function(angular){
angular.module('app.login',[])
.controller('LoginController',function($scope,userService){
$scope.user={
loginname:{requiredTip:'必须填写用户名!'},
password:{requiredTip:'必须填写密码!'},
error:{}
};
$scope.submit=function(){
userService.login($scope.user.loginname.value,$scope.user.password.value,function(data){
if(data.success){
//登录令牌和权限通过service回调回来,分别在data.token和data.auth中
//转到主页代码省略
}else{
$scope.user.error.tip=data.msg;
}
});
};
});
})(window.angular);
注意这里的服务userService为依赖注入
4、userService.js(用户相关业务逻辑的服务)
(function(angular){
angular.module('app.login')
.factory('userService',function($http){
return {
http:$http,
token:'',
auth:'',
login:function(loginname,password,fn){
this.http({
//这里将改为请求协同平台的webserver,返回登录令牌和权限
url:'../../scripts/loginModule/services/loginOKTest.js',
method:'GET'
})
//data,header,config,status
.success(Base.bindArguments(this,function(){
var data=arguments[0][0];
fn(data[0]);
if(data[0].success){
this.token=token;
this.auth=auth;
}
}))
.error(function(data,header,config,status){
alert("服务申请失败!");
});
},
//全局单例,因此令牌可以在任何注入的地方获得
getToken:function(){
return this.token;
},
//全局单例,因此权限可以在任何注入的地方获得
getAuth:function(){
return this.auth;
}
};
});
})(window.angular);
注意server为全局单例
base.bindArguments是一个上下文转换工具,返回一个调用call的闭包