Spring Boot的web开发

基于Bootstrap和AngularJS的现代Web应用
现代的B/S系统特色
1.单页面应用(single-page application,简称SPA)
所有资源(html、js、css)都按需动态加载到页面上,且不需要服务端控制页面页面的转向
2.响应式设计(Responsive web design,简称RWD)
不同设备访问相同页面,得到不同页面视图,得到的视图是适应当前屏幕的。
3.数据导向
针对于页面导向而言,页面上的数据获得是通过消费后台的REST服务来实现的,而不是通过服务器渲染的动态页面实现,一般数据交换使用的格式是JSON
1.Bootstrap
Bootstrap定义:Bootstrap是开发响应式和移动优先的Web应用的最流行的HTML、css、JavaScript框架
Bootstrap实现了只使用一套代码就可以在不同设备显示你想要的视图的功能。提供了大量美观的HTML元素前端组件和jQuery插件。
1.1 下载并引入Bootstrap
1.2 CSS支持
Bootstrap的CSS样式为基础的HTML元素提供了美观的央视,此外提供了高级的网格系统用来做页面布局。简单的页面模板:
<!DOCTYPE html >
< html lang= "zh-cn" >
<!-- 上面两句为HTML5的doctype -->
< head >
< meta charset= "utf-8" >
< meta http-equiv= "X-UA-Compatible" content= "IE=edge" >
< meta name= "viewport" content= "width=device-width, initial-scale=1" >
<!-- 上面3个meta标签必须是head的头三个标签,其余的head内标签在此3个之后The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
< title > Bootstrap基本模板 </ title >

<!-- Bootstrap的CSS -->
< link href= "bootstrap/css/bootstrap.min.css" rel= "stylesheet" >
<!-- HTML5 shim and Respond.js用来让IE8支持HTML5元素和媒体查询 -->
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
</ head >
< body >
< h1 > 你好, Bootstrap! </ h1 >
<!-- jQuery是Bootstrap脚本插件必须的 -->
< script src= "js/jquery.min.js" ></ script >
<!-- 包含所有编译的插件 -->
< script src= "bootstrap/js/bootstrap.min.js" ></ script >
</ body >
</ html >
1.2.1 布局网格
在Bootstrap里,行使用的样式为row,列使用col-md-数字,此数字范围为1-12,所有列加起来的和也是12.
< div class= "row" >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
< div class= "col-md-1" > .col-md-1 </ div >
</ div >
< div class= "row" >
< div class= "col-md-8" > .col-md-8 </ div >
< div class= "col-md-4" > .col-md-4 </ div >
</ div >
< div class= "row" >
< div class= "col-md-4" > .col-md-4 </ div >
< div class= "col-md-4" > .col-md-4 </ div >
< div class= "col-md-4" > .col-md-4 </ div >
</ div >
< div class= "row" >
< div class= "col-md-6" > .col-md-6 </ div >
< div class= "col-md-6" > .col-md-6 </ div >
</ div >
1.2.2 html元素
Bootstrap为html元素提供了大量的样式,如表单元素、按钮等,具体内容查看 http://getbootstrap.com/css
1.3 页面组件支持
Bootstrap提供了大量的页面组件,包括字体图标、下拉框等,更多阅读 http://getbootstrap.com/components/
1.4 javascript支持
Bootstrap提供大量JavaScript插件,如模式对话框、标签页、提示灯,更多阅读 http://getbootstrap.com/javascript/

2.AngularJS
AngularJS定义:是HTML开发本应该的样子,用来设计开发Web应用的。
AngularJS使用声明式模板+数据绑定(类似JSP、Thymeleaf)、MVW(Model-View-Whatever)、MVVM(Model-View-ViewModel)、MVC(Model-View-Controller)、依赖注入和测试,这一切实现只借助纯客户端的JS。
HTML用来声明静态页面,AngularJS可以只通过前端技术就实现动态的页面。
2.1 下载并引入AngularJS
下载地址: https://angularjs.org
简单的页面代码:
<!doctype html >
< html ng-app > <!-- ng-app所作用的范围是AngularJS起效的范围,本例是整个页面有效 -->
< head >
< meta charset= "utf-8" >
< script src= "js/angular.min.js" ></ script > <!-- 载入AngularJS的脚本 -->
</ head >
< body >
< div >
< label > 名字: </ label >
< input type= "text" ng-model= "yourName" placeholder= "输入你的名字" > <!-- ng-model定义整个AngularJS的前端数据模型,模型的名称为yourName,模型的值来自你输入的值,若输入值改变,则数据模型值也改变。 -->
< hr >
< h1 > 你好 {{yourName}}! </ h1 > <!-- 使用{{模型名}}来读取模型中的值 -->
</ div >
</ body >
</ html >

2.2 模块、控制器和数据绑定
用AngularJS实现纯页面端的MVC,即 实现了视图模板、数据模板、代码控制的分离
数据绑定是将视图和数据模型绑定在一起。如果视图变了,模型的值也随着变了,反之一样。
AngularJS为了分离代码达到复用的效果,提供了一个module(模块)。定义一个模块需要下面的代码。
无依赖模块:angular.module('firstModule',[]);
有依赖模块:angular.module('firstModule',['moduleA','moduleB']);
V就是页面元素,M就是ng-model,C就是ng-controller(页面通过ng-controller来与其关联)
angular.module('firstModule',[])
.controller('firstController',function(){
.....
};
);

<div ng-controller="firstController">
...
</div>
2.3 Scope和Event
(1) Scope
Scope是AngularJS的内置对象,用$Scope获得。在Scope中定义的数据是数据模型,可以通过
{{模型名}}在视图上获得。
Scope主要是在编码中需要对数据模型进行处理的时候使用。
Scope的作用范围与在页面声明的范围一致(如在controller内使用,scope的作用范围是页面声明2ng-controller标签元素的作用范围)
定义:$scope.greeting='Hello'
获取:{{greeting}}
(2)Event
因为Scope的作用范围不同,所以不同的Scope之间若要交互的话需要通过事件(Event)来完成
1)冒泡事件(Emit)冒泡事件负责从子Scope向上发送事件
子Scope发送:
$scope.$emit('EVENT_NAME_EMIT',''message);
父Scope接受:
$scope.$on(''EVENT_NAME_EMIT',function(event,data){
.......})
2)广播事件(Broadcast).广播事件负责从父Scope向下发送事件。
父Scope发送:
$scope.$broadcast('EVENT_NAME_BROAD','message');
子scope接受:
$scope.$on(''EVENT_NAME_BROAD',function(event,data){
.......})
2.4 多视图和路由
多视图和路由是AngularJS实现单页面应用的技术关键,AngularJS内置了一个$routeProvider对象来负责页面加载和页面路由转向。
注意:1.2.0之后的AngularJS将路由功能移出 所以使用路由功能要另外引入angular-route.js
例如:
angular.module('firstModule').config(function($routeProvider){
$routeProvider.when('/view1',{//此处定义的是某个页面的路由名称
controller:'Controller1',//此处定义的是当前页面使用的控制器
templateUrl:'view1.html',//此处定义的是加载的真实页面
}).when('/view2',{
controller:'Controller2',
templateUrl:'view2.html',
});
})

在页面上可以用下面代码来使用我们定义的路由:
<ul>
<li><a href="#/view1">view1</a></li>
<li><a href="#/view2">view2</a></li>
</ul>
<ng-view></ng-view><!--此处为加载进来的页面显示的位置-->

2.5 依赖注入
依赖注入是AngularJS的重要功能,可以实现对代码的解耦,在代码里可以注入AngularJS的对象或者我们自定义的对象。
在控制器注入$scope,注意使用依赖注入的代码格式:
angular.module('firstModule') .controller("diController",{'$scope',function($scope){
.........}});

2.6 Service和Factory
AngularJS内置了一些服务,如$location、$timeout、$root.
自己定制服务,AngularJS提供了Service和Factory
Service:AngularJS使用new来初始化对象
Factory:直接获得对象
(1) Service
定义:
angular.module('firstModule').service('helloService',function(){
this.sayHello=function(name){
alert('Hello'+name);
}
});
注入调用:
angular.module('firstModule').controller("diController",['$scope','helloService',
function($scope,helloService){
helloService.sayHello('lqy');
}]);
(2) Factory
定义:
angular.module('firstModule'.service('helloFactory',function(){
return{
sayHello:function(name){
alert('Hello'+name);
}
}
}));
注入调用:
angular.module('firstModule').controller("diController",['$scope','helloFactory',
function($scope,helloFactory){
helloFactory.sayHello('lqy');
}]);
2.7 自定义指令
AngularJS内置了大量的指令(directive),如ng-repeat、ng-show、ng-model等。即使用一个简短的指令可实现一个前端组件。
举例:一个日期的js/jQuery插件,使用AngularJS封装后,在页面上调用该插件可以通过指令实现。
元素指令:<date-picker></date-picker>
属性指令:<input type="text" date-picker/>
样式指令:<input type="text" class="date-picker"/>
注释指令:<!-- directive;date-picker-->
定义指令:
angular.module('myApp',[]).directive('helloWorld',function(){
return {
restrict:'AE',//支持使用属性、元素
replace:true,
template:'<h3>Hello,World!</h3>'
};
});
调用指令,元素标签:
<hello-world/>
<hello:world/>
属性方式:
<div hello-world/>


实战
使用Bootstrap制作导航,使用AngularJS实现导航切换页面的路由功能,
并演示AngularJS通过$http服务和Spring Boot提供的REST服务,最后演示用指令封装jQueryUI的日期选择器。
1.新建Spring Boot项目
选择Web依赖(spring-boot-starter-web)
准备Bootstrap、AngularJS、jQuery、jQueryUI相关的资源到src/main/resources/static下。(静态页面统一放到static下)

2.制作导航
页面位置:src/main/resources/static/action.html
<!DOCTYPE html >
< html lang= "zh-cn" ng-app= "actionApp" >
< head >
< meta charset= "utf-8" >
< meta http-equiv= "X-UA-Compatible" content= "IE=edge" >
< meta name= "viewport" content= "width=device-width, initial-scale=1" >
< title > 实战 </ title >
<!-- Bootstrap的CSS -->
< link href= "bootstrap/css/bootstrap.min.css" rel= "stylesheet" >
< link href= "jqueryui/jquery-ui.min.css" rel= "stylesheet" >
< style type= "text/css" >

. content {
padding : 100 px 15 px ;
text-align : center ;
}
</ style >
<!--[if lt IE 9]>
<script src="js/html5shiv.min.js"></script>
<script src="js/respond.min.js"></script>
<![endif]-->
</ head >
<!--使用Bootstrap定义的导航,并配合AngularJS的路由,通过路由名称#/oper和#/directive切换视图 -->
< body >
< nav class= "navbar navbar-inverse navbar-fixed-top" >
< div class= "container" >
< div id= "navbar" class= "collapse navbar-collapse" >
< ul class= "nav navbar-nav" >
< li >< a href= "#/oper" > 后台交互 </ a ></ li >
< li >< a href= "#/directive" > 自定义指令 </ a ></ li >
</ ul >
</ div > <!--/.nav-collapse -->
</ div >
</ nav >
<!--通过<ng-view></ng-view>展示载入的页面-->
< div class= "content" >
< ng-view ></ ng-view >
</ div >
<!--加载本例所需的脚本,其中jquery-ui.min.js的脚本是为定制指令所用;
app.js定义AngularJS的模块和路由;
directives.js为自定义的指令;
controllers.js是控制器定义之处 -->
< script src= "js/jquery.min.js" ></ script >
< script src= "jqueryui/jquery-ui.min.js" ></ script >
< script src= "bootstrap/js/bootstrap.min.js" ></ script >
< script src= "js/angular.min.js" ></ script >
< script src= "js/angular-route.min.js" ></ script >
< script src= "js-action/app.js" ></ script >
< script src= "js-action/directives.js" ></ script >
< script src= "js-action/controllers.js" ></ script >
</ body >
</ html >
3.模块和路由定义
页面位置:src/main/resources/static/js-action/app.js
/**
*
*/
var actionApp = angular .module( 'actionApp' ,[ 'ngRoute' ]); //定义模块actionApp,并依赖于路由模块ngRoute
actionApp . config ([ '$routeProvider' , function ($routeProvider) { //配置路由,并注入$routeProvider来配置
$routeProvider. when ( '/oper' , { //oper为路由名称
controller : 'View1Controller' , //controller定义的是路由的控制器名称
templateUrl : 'views/view1.html' , //templateUrl定义的是视图的真正地址
}). when ( '/directive' , {
controller : 'View2Controller' ,
templateUrl : 'views/view2.html' ,
});
}]);
4.控制器定义
脚本位置:src/main/resources/static/js-action/controllers.js
/**
*
*/
//定义控制器View1Controller,并注入$rootScope、$scope和$http
actionApp . controller ( 'View1Controller' , [ '$rootScope' , '$scope' , '$http' ,
function ($rootScope, $scope,$http) {
//使用$scope.$on监听$viewContentLoaded事件,可以在页面内容加载完成后进行一些操作
$scope. $on ( '$viewContentLoaded' , function () {
console . log ( '页面加载完成' );
});
//这段代码是演示的核心代码,结合View的界面一起理解:
/**
* 1.在scope内定义一个方法search,在页面上通过ng-click调用。
* 2.通过$scope.personName获取页面定义的ng-model="personName"的值
* 3.使用$http.get向服务端地址search发送get请求
* 4.使用params增加请求参数。
* 5.用success方法作为请求成功后的回调
* 6.将服务器返回的数据data通过$scope.person赋给模型person,
* 这样页面视图上可以通过{{person.name}}、{{person.age}}、{{person.address}}来调用,
* 且模型person值改变后,视图是自动更新的。
*/
$scope. search = function (){ //1
personName = $scope. personName ; //2
$http.get( 'search' ,{ //3
params :{ personName : personName } //4
}). success ( function (data){ //5
$scope. person =data; //6
});;
};
}]);
actionApp . controller ( 'View2Controller' , [ '$rootScope' , '$scope' , function ($rootScope, $scope) {
$scope. $on ( '$viewContentLoaded' , function () {
console . log ( '页面加载完成' );
});
}]);
5.View1的界面(演示与服务端交互)src/main/resources/static/views/view1.html
< div class= "row" >
< label for= "attr" class= "col-md-2 control-label" > 名称 </ label >
< div class= "col-md-2" >
<!-- 定义数据模型ng-model="personName" -->
< input type= "text" class= "form-control" ng-model= "personName" >
</ div >
< div class= "col-md-1" >
<!-- 通过ng-click="search()"调用控制器中定义的方法 -->
< button class= "btn btn-primary" ng-click= "search()" > 查询 </ button >
</ div >
</ div >
< div class= "row" >
< div class= "col-md-4" >
< ul class= "list-group" >
<!-- 通过{{person.name}}、{{person.age}}、{{person.address}}访问控制器的scope里定义person模型,模型和视图是绑定的 -->
< li class= "list-group-item" > 名字: {{person.name}} </ li >
< li class= "list-group-item" > 年龄: {{person.age}} </ li >
< li class= "list-group-item" > 地址: {{person.address}} </ li >
</ ul >
</ div >
</ div >

6.服务端 代码
传值对象Javabean:
package com.hand;

public class Person {
private String name ;
private Integer age ;
private String address ;
public Person() {
super ();
}
public Person(String name, Integer age, String address) {
super ();
this . name = name;
this . age = age;
this . address = address;
}
public String getName() {
return name ;
}
public void setName(String name) {
this . name = name;
}
public Integer getAge() {
return age ;
}
public void setAge(Integer age) {
this . age = age;
}
public String getAddress() {
return address ;
}
public void setAddress(String address) {
this . address = address;
}
}
7.自定义指令:src/main/resources/static/js-action/directives.js;
/**
* 定制了一个封装jqueryui的datePicker的指令
*/
actionApp . directive ( 'datePicker' , function (){ //定义一个指令名为datePicker
return {
restrict : 'AC' , //限制为属性指令和样式指令
link : function (scope,elem,attrs){ //使用link方法来定义指令,在Link方法内可使用当前scope,当前元素及元素属性
// scope.treeObj = $.fn.zTree.init(elem, scope.settings);
elem. datepicker (); //初始化jqueryui的dataPicker(jquery的写法是$('#id').dataPicker())
}
};
});
8.View2的页面(演示自定义指令)
< div class= "row" >
< label for= "attr" class= "col-md-2 control-label" > 属性形式 </ label >
< div class= "col-md-2" >
<!-- 使用属性形式调用指令 -->
< input type= "text" class= "form-control" date-picker >
</ div >
</ div >
< div class= "row" >
< label for= "style" class= "col-md-2 control-label" > 样式形式 </ label >
< div class= "col-md-2" >
<!-- 使用样式形式调用指令 -->
< input type= "text" class= "form-control date-picker" >
</ div >
</ div >
9.运行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值