AngularJS入门
AngularJS核心的特性就是:MVC模式、模块化、双向绑定、依赖注入等特性。利用AngularJS,我们能很方便的实现HTML页面和后端的数据交互,让我们逐步脱离JSP页面;HTML+Javascript+AJAX技术让我们能够做出来更轻的Web应用。
AngularJS四大特征
MVC模式
Model:数据,相当于angular中的变量($scope.Xxx)(这个变量可以是单一的变量,也可以是实体对象)。
View:数据的呈现:HTML+Directive(指令)
Controller:操作数据,就是function方法,实现数据的增删改查操作等。
双向绑定
AngularJS第二个重要特性就是双向绑定,即使用AngularJS
绑定的变量,能够在AngularJS
的MVC三层模式中动态的改变。视图层(HTML)绑定的变量传递到控制层(function),控制层能够获取到绑定变量并传递给后端映射进行处理,处理后的数据通过AngularJS
获取到并仍能够返回到视图层页面,改变原有视图层的数据。
依赖注入
Spring中的依赖注入(DI)思想,在AngularJS
中同样存在。即某个对象依赖的其他对象无需自己手动注入,在该对象创建的时候,起依赖对象就由框架自动创建并注入进来。同后端我们将Service层注入到Controller层,并不需要我们自己手动new
依赖对象,即由框架帮我们完成了注入。
模块化设计
高内聚低耦合法则
- 官方提供的模块: ng、ngRote、ngAnimate
- 用户自定义的模块: angular.module(‘模块名’,[])
案例
表达式
1 2 3 4 5 6 7 8 9 10 11 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Angular入门案例</title> </head> <body ng-app> {{1024+1024}} </body> <script src="../static/plugins/angular/angular.min.js"></script> </html> |
- 使用
AngularJS
首先要引入angular的JS文件。 AngularJS
的表达式用法就是:,这个表达式也可以是由AngularJS
绑定的对象。<body>
中的ng-app
指令:告诉子元素,以下的其他AngularJS
指令都会被AngularJS
识别。ng-app
指令定义了AngularJS
应用程序的根元素。ng-app
指令在网页加载完毕时会自动初始化应用程序。
双向绑定
1 2 3 4 5 6 7 8 9 10 11 12 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Angular入门案例</title> </head> <body ng-app> 姓名:<input ng-model="name"/><br/> hello: {{name}} </body> <script src="../static/plugins/angular/angular.min.js"></script> </html> |
ng-model
用于绑定变量,被绑定的变量能够在AngularJS
中动态的改变数据。
其他指令
1. `ng-init=""` 用于初始化数据。
2. `ng-click=""` 元素被点击时被触发,可以是一个对应的`AngularJS`控制层方法
3. `ng-controller=""` 用于指定该视图层使用的控制器名称。
4. ...
控制器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Angular入门案例</title> </head> <body ng-app="testApp" ng-controller="testController"> a: <input ng-model="a"><br/> b: <input ng-model="b"><br/> <button ng-click="test()">计算</button> a+b: {{result}} </body> <script src="../static/plugins/angular/angular.min.js"></script> <script type="text/javascript"> //声明一个testApp模块 var app = angular.module('testApp',[]); //定义控制器 app.controller('testController',function($scope){ $scope.test = function(){ $scope.result = parseInt($scope.a) + parseInt($scope.b); } }); </script> </html> |
- 首先在
<body>
中标识使用的ng-app
对象和ng-controller
对象。 - 使用
angular.module('模块名称',[])
的方式创建angularJS
的模块对象。 - 使用
模块名.controller('控制器名',function(){})
的方式定义控制器,写对应的业务代码。同样模块名.service('服务层名',function(){})
的方式创建服务器。 $scope
使用贯穿了整个AngularJS
应用,它在Angular
控制层和视图层建立了一个通道,基于作用域视图在修改数据时会立刻更新$scope
,同样的$scope
发生改变时也会立刻重新渲染视图。
遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Angular入门案例</title> </head> <body ng-app="testApp" ng-controller="testController"> <table> <tr> <td>编号</td> <td>名称</td> </tr> <tr ng-repeat="entity in list"> <td>{{entity.id}}</td> <td>{{entity.name}}</td> </tr> </table> </body> <script src="../static/plugins/angular/angular.min.js"></script> <script type="text/javascript"> //声明一个testApp模块 var app = angular.module('testApp',[]); //定义控制器 app.controller('testController',function($scope){ $scope.list = [{id:1,name:'张珊'}, {id:2,name:'小菜'}]; }); </script> </html> |
如上我们使用ng-repeat
指令即可实现数据的遍历,和JSP中的<forEach>
标签是不是有些雷同呢?如上其实我们是将需要遍历的数据存入到AngularJS
绑定的对象list
中,然后使用ng-repeat
指令遍历这个对象获取数据。
注意: 在list
对象中定义的数据格式,AngularJS
本身就规定了你的对象中数据必须是这种格式的(当然你可以使用JSON格式数据),但是此处定义的数据并不是标准的JSON格式数据,但是这两种格式数据都能被AngularJS
识别。
标准的JSON数据格式:
1 | {"id": 1, "name": "张珊"} |
JSON数据格式规定了其key
和value
都必须""
隔开,使用''
也不行。
代码分层
思路
在上面我们一直强调AngularJS
的MVC设计模式,那么同后端,将对应的代码进行分层不是更方便维护嘛。所以我们将AngularJS
代码分为三层:
- HTML(视图层):即页面的HTML代码,其中包含了
AngularJS
标识的变量。 - Controller(控制层):即存放主要的业务逻辑的代码(各种function()方法)。
- Service(业务层):这个业务层和我们后端中的业务层不同,因为我们将主要的业务逻辑代码存放到了Controller层,所以这里的
Service
层存放的是和后端交互的请求路径。
即我们通过在HTML(视图层)绑定变量或对象,在Controller中获取到(通过$scope
获取),调用Service
层对应的请求路径方法,通过Controller
层中的请求回调方法(.success(function(response){})
),获取到请求响应的数据(response
),然后利用AngularJS
的双向绑定特性将数据赋值到HTML(视图层)的指定区域。
目录结构
如上,为了方便,我将文件都放在一个test
文件夹中,实际中,我们可以分别建立service
,controller
文件夹存放对应的代码。其中:
data.json
是我们模拟请求后端而写的json
格式数据(注意:实际中我们后端的请求也要返回JSON
格式数据)。angular-base.js
存放了创建的angularJS
模块方法,即var app = angular.module('模块名',[])
。angular-controller.js
存放controller
层的逻辑代码,通过app.controller('控制器名',function(){})
声明。angular-service.js
存放service
层对应的代码,通过app.service('业务层名',function(){})
声明。angular-demo.html
视图层,主要是页面实现的代码,其中包含被angular
绑定的变量,并且这些被绑定的对象需要在ng-app="模块名"
、ng-controller="控制器名"
的标识的区域下(父层节点上,通常我们将其定义在<body>
体中)。
模拟的后端相应的数据
data.json
1 2 3 4 5 | [ {"id": 1, "name": "涂陌"}, {"id": 2, "name": "TyCoding"}, {"id": 3, "name": "大白"} ] |
自定义angular模块
angular-base.js
1 | var app = angular.module('baseApp',[]); |
业务层
angular-service.js
1 2 3 4 5 6 | //定义业务层 app.service('testService', function($http){ this.findAll = function(){ return $http.get('data.json'); } }); |
其中包含了AngularJS
内置的服务$http
,可以让我们方便的请求后端,包含$http.get()
,$http.post()
等请求方式。
控制层
angular-controller.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //定义控制器 app.controller('testController', function ($scope, $controller, testService) { //伪继承 //$controller('baseController',{$scope:$scope}); //获取数据 $scope.findAll = function(){ testService.findAll().success( function(response){ $scope.list = response; } ); } }); |
- 在上面我们已经解释了
controller
层声明的方式,就是app.controller()
方式,其中function($scope,$controller,testService)
是在此controller
层需要使用的对象,其中testService
就体现出了angular的依赖注入思想,testService
其实是service
层的名称,当在controller
中需要使用这个service
的对象,直接在声明controller
时就因入其名称即可,angular会自动帮我们将service
对象注入到controller
中。 - 这里我们再注释中添加了伪基层的实现代码。在
AngularJS
中也存在继承的思想,但是仅仅是伪继承,因为可以看到AngularJS
的继承就是将baseController
中的$scope
对象赋值给当前控制器中$scope
。这样,在当前的控制器中就能使用baseController
中定义的对象或者方法了。 - 在调用了
testService
中的方法findAll()
后,service
请求相应的数据都存在在回调函数.success(function(response){})
的response
中,我们通过$scope.list
获取到页面中绑定的对象,并将当前相应的数据赋值给list
中,视图层(HTML)就能通过取JSON格式数据的方式将数据取出来。
视图层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Angular入门案例</title> </head> <body ng-app="baseApp" ng-controller="testController" ng-init="findAll()"> <table> <tr> <td>编号</td> <td>名称</td> </tr> <tr ng-repeat="entity in list"> <td>{{entity.id}}</td> <td>{{entity.name}}</td> </tr> </table> </body> <script src="../static/plugins/angular/angular.min.js"></script> <script src="../static/plugins/jquery/jquery-3.3.1.min.js"></script> <script src="../test/angular-base.js"></script> <script src="../test/angular-service.js"></script> <script src="../test/angular-controller.js"></script> </html> |
在视图层中通过ng-repeat=""
来遍历后端存储了响应数据的对象list
,通过的方式将数据取出来,其实就是取JSON数据的方式,因此我们也必须将请求响应的封装层JSON格式。
这样我们就实现和后端的交互,并将数据回显到了页面上,是不是比JSP要方便快捷很多呢?
终
同上上面的学习,我们已经了解到了怎样在HTML页面上利用AngularJS
完成和后端数据的交互。下面大家来看一下我在实际开发中实现的常见的增删改查的操作:
页面
controller层
service层
实际效果