看书和视频结合是学习的最高效方式,看了这本书之后对angularjs才算是有一定的理解了。这本书以搭建一个博客为线索讲解了angularjs的知识点和实际项目开发流程。非常适合初学者!下面是我的读书笔记。
一、传统与AngularJS开发模式对比
传统的web框架如Apache Struts、SpringMVC等mvc框架是主流。web mvc框架完全在服务器运行,所有功能,比如说访问数据库、业务逻辑、显示逻辑和UI活动都在服务器中完成,因此要消耗服务器的内存和资源。
传统web框架通常会是在服务器端使用PHP、ASP、JSP等脚本渲染页面,但是这样会带来很多维护方面的问题。不过这不是传统方式最严重的问题,最严重的问题是传统web框架在移动设备中大都运行缓慢,而与桌面用户相比,移动设备的用户更加不能忍受系统延迟和加载缓慢。因为所有的视图、模型、控制数据库都在后端,而用户的硬件只起到了展示网页的功能。
AngularJS是在移动设备高速普及的情况下,顺应未来趋势而生的客户端js框架,它比起传统的方式,整个Angularjs都运行在用户的硬件中,而后端使用REST web服务处理业务逻辑,REST可以运行在任何地方,也可以使用任何编程语言编写,流行使用JAVA的spring框架或者node.js平台下的Expressjs开发。Angular充分利用了用户的硬件,完全解放了服务器,或者只让服务器处理业务逻辑和数据存储。能够让应用在任何设备下都能良好运行。
二、Angularjs的控制器
1、创建控制器
下面我创建了一个名为myApp的模块,并且为这个模块加上一个名为myAppctrl的控制器
var myApp = angular.module('myApp',[]); //在angular对象上调用module方法创建了一个名为myApp的模块。 myApp.controller('myAppctrl', ['$scope','$checkCreds','$location','$http', //在刚刚创建的myApp的模块上又调用了controller方法,定义此控制器的名字为 //myAppctrl。并且[]为这个控制器的依赖,在angular中这称为依赖注入 function (){ //回调函数 }]);
2、控制器的作用
控制器有两个职责,第一个是初始化作用域中的模型属性。创建控制器并将其附加到DOM中之后,会创建一个子作用域,子作用域中保存着一个所属控制器专用的模型。子作用域可以通过$scope对象获取。
我在控制器myAppctrl上添加了两个属性到作用域中name和number
var myApp = angular.module('myApp',[]); //在angular对象上调用module方法创建了一个名为myApp的模块。 myApp.controller('myAppctrl', ['$scope','$checkCreds','$location','$http', //在刚刚创建的myApp的模块上又调用了controller方法,定义此控制器的名字为 //myAppctrl。并且[]为这个控制器的依赖,在angular中这称为依赖注入 function myAppctrl($scope){ //回调函数 $scope.name = "lq"; $scope.number = "123"; }]);
接下来就可以在视图模板中访问刚刚添加的两个模型属性,访问方法为双花括号
<div><b>name:</b>{{name}}</div> <div><b>name:</b>{{number}}</div>
控制器的第二个作用是把行为附加到$scope对象上。附加行为的方式是,在$scope对象上添加方法,在$scope对象上添加了一个changeName的方法
$scope.changeName = function(){ $scope.name = $scope.cName; $scope.number = $scope.cNumber; }
那我们在视图模板中怎么使用这个方法呢?
我们使用ng-model="cName",ng-model="cNumber"向模型中添加两个新属性,然后使用ng-click="changeName();"调用刚刚添加到changeName方法。
<form> <div> <input type="text" ng-model="cName" required/> </div> <div> <input type="number" ng-model="cNumber" required/> </div> <div><button ng-click="changeName();">change Name</button></div> </form>
三、Angular视图
视图由html代码构成,外加一些指令。它是在运行时动态构建视图,合并多个模板,渲染通过$scope对象传入模板的属性。渲染视图的结果是纯样的html绑定在ng-view指令上。ng-repeat是十分常用的表现方式,它相当于是一个for循环,比如说你在控制器中的$scope对象上添加了一个存储数据的json对象list,就可以采用ng-repeat指令来循环这个json对象并把它展现出来。
四、Angular模型
Angular模型保存在$scope对象中,$scope用于访问某个控制器对应的模型。$rootScope是父级作用域,用于保存和访问在多个控制器中使用的模型属性。不过不建议使用$rootScope对象,一个应用中只有一个$rootScope对象,$scope对象是$rootScope对象的子作用域。在开发中我们只要在作用域定义好模型属性,这些属性就可以在视图中访问了,而不需修改视图。
五、Angular的REST服务
rest服务(REpresentational state transfer)表现层状态转化服务的目的是“分离关注点”它是无状态的。REST不能在会话中保存数据。REST服务所需的任何信息都应该放在客户端传给服务的请求和首部中。任何状态都应该保存在客户端,而不能保存在服务器,在Angular中保存状态的方式很多,例如本地存储、cookie或缓存。只有满足以下条件的web服务才称得是REST式服务:
1、能通过URL访问
2、使用某种互联网媒介类型如json交换数据
3、使用标准的HTTP请求方法get post put delete
angularjs通过ajax请求异步调用rest服务,这种ajax请求基于$q服务的Promise对象和deferred对象实现。在angular中创建并注册服务有三种方式
1、使用service函数。 2、使用provider函数 3、使用factory函数(最常用)
angularjs与rest服务通信的方式:
1、$http服务,这个服务通过浏览器的XMLHttpRequest对象实现与rest服务的低层交互 2、$resource对象 这个对象提供与rest服务交互的高层方式,极大简化了通信过程。
下面我定义了一个与rest服务交互的angularjs服务
var blogServices=angular.module('services',['ngResource']); blogServices.factory('BlogPost', ['$resource', function($resource){ return $resource(url, paramDefaults, actions) }])
六、服务和业务逻辑
不是所有业务逻辑都在rest服务中,这些业务逻辑通常要在多个控制器中使用,这个时候非rest服务就有用了。比如:
1、认证用户,由于rest服务不能保存状态,而且在服务器的会话中保存用户的认证凭证有安全隐患,所以这时使用angularjs服务最好。
七、Angularjs指令
从用户的角度,指令directive就是在应用的模板中使用的自定义html标签。angularjs的html编译器会解析指令,增强模板的功能。而这个编译器不是正在意义的编译而是搜索DOM树,找出与指令关联的html元素,找到所关联的元素后,编译器会构建模板,把事件附加到模板中的这些元素上。当然我们也可以自定义指令。